Skip to content

Commit 61d7e0a

Browse files
feat: refactor pyth lazer protocol (#2945)
1 parent d0abcdc commit 61d7e0a

File tree

9 files changed

+73
-63
lines changed

9 files changed

+73
-63
lines changed

Cargo.lock

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lazer/contracts/solana/Cargo.lock

Lines changed: 3 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ no-log-ix-name = []
1919
idl-build = ["anchor-lang/idl-build"]
2020

2121
[dependencies]
22-
pyth-lazer-protocol = { path = "../../../../sdk/rust/protocol", version = "0.13.0" }
22+
pyth-lazer-protocol = { path = "../../../../sdk/rust/protocol", version = "0.14.0" }
2323

2424
anchor-lang = "0.31.1"
2525
bytemuck = { version = "1.20.0", features = ["derive"] }

lazer/publisher_sdk/rust/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
[package]
22
name = "pyth-lazer-publisher-sdk"
3-
version = "0.8.0"
3+
version = "0.9.0"
44
edition = "2021"
55
description = "Pyth Lazer Publisher SDK types."
66
license = "Apache-2.0"
77
repository = "https://github.com/pyth-network/pyth-crosschain"
88

99
[dependencies]
10-
pyth-lazer-protocol = { version = "0.13.0", path = "../../sdk/rust/protocol" }
10+
pyth-lazer-protocol = { version = "0.14.0", path = "../../sdk/rust/protocol" }
1111
anyhow = "1.0.98"
1212
protobuf = "3.7.2"
1313
serde_json = "1.0.140"

lazer/sdk/rust/client/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
[package]
22
name = "pyth-lazer-client"
3-
version = "5.0.0"
3+
version = "6.0.0"
44
edition = "2021"
55
description = "A Rust client for Pyth Lazer"
66
license = "Apache-2.0"
77

88
[dependencies]
9-
pyth-lazer-protocol = { path = "../protocol", version = "0.13.0" }
9+
pyth-lazer-protocol = { path = "../protocol", version = "0.14.0" }
1010
tokio = { version = "1", features = ["full"] }
1111
tokio-tungstenite = { version = "0.20", features = ["native-tls"] }
1212
futures-util = "0.3"

lazer/sdk/rust/protocol/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "pyth-lazer-protocol"
3-
version = "0.13.0"
3+
version = "0.14.0"
44
edition = "2021"
55
description = "Pyth Lazer SDK - protocol types."
66
license = "Apache-2.0"

lazer/sdk/rust/protocol/src/price.rs

Lines changed: 43 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -27,39 +27,39 @@ pub struct Price(NonZeroI64);
2727

2828
impl Price {
2929
pub fn from_integer(value: i64, exponent: i16) -> Result<Price, PriceError> {
30-
let value = match ExponentFactor::get(exponent).ok_or(PriceError::Overflow)? {
30+
let mantissa = match ExponentFactor::get(exponent).ok_or(PriceError::Overflow)? {
3131
ExponentFactor::Mul(coef) => value.checked_mul(coef).ok_or(PriceError::Overflow)?,
3232
ExponentFactor::Div(coef) => value.checked_div(coef).ok_or(PriceError::Overflow)?,
3333
};
34-
let value = NonZeroI64::new(value).ok_or(PriceError::ZeroPriceUnsupported)?;
35-
Ok(Self(value))
34+
let mantissa = NonZeroI64::new(mantissa).ok_or(PriceError::ZeroPriceUnsupported)?;
35+
Ok(Self(mantissa))
3636
}
3737

3838
pub fn parse_str(value: &str, exponent: i16) -> Result<Price, PriceError> {
3939
let value: Decimal = value.parse()?;
40-
let value = match ExponentFactor::get(exponent).ok_or(PriceError::Overflow)? {
40+
let mantissa = match ExponentFactor::get(exponent).ok_or(PriceError::Overflow)? {
4141
ExponentFactor::Mul(coef) => value
4242
.checked_mul(Decimal::from_i64(coef).ok_or(PriceError::Overflow)?)
4343
.ok_or(PriceError::Overflow)?,
4444
ExponentFactor::Div(coef) => value
4545
.checked_div(Decimal::from_i64(coef).ok_or(PriceError::Overflow)?)
4646
.ok_or(PriceError::Overflow)?,
4747
};
48-
if !value.is_integer() {
48+
if !mantissa.is_integer() {
4949
return Err(PriceError::TooPrecise);
5050
}
51-
let value: i64 = value.try_into().map_err(|_| PriceError::Overflow)?;
52-
let value = NonZeroI64::new(value).ok_or(PriceError::Overflow)?;
53-
Ok(Self(value))
51+
let mantissa: i64 = mantissa.try_into().map_err(|_| PriceError::Overflow)?;
52+
let mantissa = NonZeroI64::new(mantissa).ok_or(PriceError::Overflow)?;
53+
Ok(Self(mantissa))
5454
}
5555

5656
pub const fn from_nonzero_mantissa(mantissa: NonZeroI64) -> Self {
5757
Self(mantissa)
5858
}
5959

6060
pub const fn from_mantissa(mantissa: i64) -> Result<Self, PriceError> {
61-
if let Some(value) = NonZeroI64::new(mantissa) {
62-
Ok(Self(value))
61+
if let Some(mantissa) = NonZeroI64::new(mantissa) {
62+
Ok(Self(mantissa))
6363
} else {
6464
Err(PriceError::ZeroPriceUnsupported)
6565
}
@@ -75,81 +75,86 @@ impl Price {
7575

7676
pub fn to_f64(self, exponent: i16) -> Result<f64, PriceError> {
7777
match ExponentFactor::get(exponent).ok_or(PriceError::Overflow)? {
78-
// Mul/div is reversed for this conversion
78+
// Mul/div is reversed for converting mantissa to value
7979
ExponentFactor::Mul(coef) => Ok(self.0.get() as f64 / coef as f64),
8080
ExponentFactor::Div(coef) => Ok(self.0.get() as f64 * coef as f64),
8181
}
8282
}
8383

8484
pub fn from_f64(value: f64, exponent: i16) -> Result<Self, PriceError> {
8585
let value = Decimal::from_f64(value).ok_or(PriceError::Overflow)?;
86-
let value = match ExponentFactor::get(exponent).ok_or(PriceError::Overflow)? {
86+
let mantissa = match ExponentFactor::get(exponent).ok_or(PriceError::Overflow)? {
8787
ExponentFactor::Mul(coef) => value
8888
.checked_mul(Decimal::from_i64(coef).ok_or(PriceError::Overflow)?)
8989
.ok_or(PriceError::Overflow)?,
9090
ExponentFactor::Div(coef) => value
9191
.checked_div(Decimal::from_i64(coef).ok_or(PriceError::Overflow)?)
9292
.ok_or(PriceError::Overflow)?,
9393
};
94-
let value: i64 = value.try_into().map_err(|_| PriceError::Overflow)?;
94+
let mantissa: i64 = mantissa.try_into().map_err(|_| PriceError::Overflow)?;
9595
Ok(Self(
96-
NonZeroI64::new(value).ok_or(PriceError::ZeroPriceUnsupported)?,
96+
NonZeroI64::new(mantissa).ok_or(PriceError::ZeroPriceUnsupported)?,
9797
))
9898
}
9999

100-
pub fn add_with_same_mantissa(self, other: Price) -> Result<Self, PriceError> {
101-
let value = self
100+
pub fn add_with_same_exponent(self, other: Price) -> Result<Self, PriceError> {
101+
let mantissa = self
102102
.0
103103
.get()
104104
.checked_add(other.0.get())
105105
.ok_or(PriceError::Overflow)?;
106-
Self::from_mantissa(value).map_err(|_| PriceError::ZeroPriceUnsupported)
106+
Self::from_mantissa(mantissa).map_err(|_| PriceError::ZeroPriceUnsupported)
107107
}
108108

109-
pub fn sub_with_same_mantissa(self, other: Price) -> Result<Self, PriceError> {
110-
let value = self
109+
pub fn sub_with_same_exponent(self, other: Price) -> Result<Self, PriceError> {
110+
let mantissa = self
111111
.0
112112
.get()
113113
.checked_sub(other.0.get())
114114
.ok_or(PriceError::Overflow)?;
115-
Self::from_mantissa(value).map_err(|_| PriceError::ZeroPriceUnsupported)
115+
Self::from_mantissa(mantissa).map_err(|_| PriceError::ZeroPriceUnsupported)
116116
}
117117

118118
pub fn mul_integer(self, factor: i64) -> Result<Self, PriceError> {
119-
let value = self
119+
let mantissa = self
120120
.0
121121
.get()
122122
.checked_mul(factor)
123123
.ok_or(PriceError::Overflow)?;
124-
Self::from_mantissa(value).map_err(|_| PriceError::ZeroPriceUnsupported)
124+
Self::from_mantissa(mantissa).map_err(|_| PriceError::ZeroPriceUnsupported)
125125
}
126126

127127
pub fn div_integer(self, factor: i64) -> Result<Self, PriceError> {
128-
let value = self
128+
let mantissa = self
129129
.0
130130
.get()
131131
.checked_div(factor)
132132
.ok_or(PriceError::Overflow)?;
133-
Self::from_mantissa(value).map_err(|_| PriceError::ZeroPriceUnsupported)
133+
Self::from_mantissa(mantissa).map_err(|_| PriceError::ZeroPriceUnsupported)
134134
}
135135

136-
pub fn mul_decimal(self, mantissa: i64, rhs_exponent: i16) -> Result<Self, PriceError> {
137-
let left_value = i128::from(self.0.get());
138-
let right_value = i128::from(mantissa);
136+
pub fn mul_decimal(self, mantissa: i64, exponent: i16) -> Result<Self, PriceError> {
137+
let left_mantissa = i128::from(self.0.get());
138+
let right_mantissa = i128::from(mantissa);
139139

140-
let value = left_value
141-
.checked_mul(right_value)
140+
// multiplied_mantissas = left_mantissa * right_mantissa
141+
let multiplied_mantissas = left_mantissa
142+
.checked_mul(right_mantissa)
142143
.ok_or(PriceError::Overflow)?;
143144

144-
let value = match ExponentFactor::get(rhs_exponent).ok_or(PriceError::Overflow)? {
145-
ExponentFactor::Mul(coef) => {
146-
value.checked_div(coef.into()).ok_or(PriceError::Overflow)?
147-
}
148-
ExponentFactor::Div(coef) => {
149-
value.checked_mul(coef.into()).ok_or(PriceError::Overflow)?
150-
}
145+
// result_mantissa = left_mantissa * right_mantissa * 10^exponent
146+
// Mul/div is reversed for multiplying 10^exponent
147+
let result_mantissa = match ExponentFactor::get(exponent).ok_or(PriceError::Overflow)? {
148+
ExponentFactor::Mul(coef) => multiplied_mantissas
149+
.checked_div(coef.into())
150+
.ok_or(PriceError::Overflow)?,
151+
ExponentFactor::Div(coef) => multiplied_mantissas
152+
.checked_mul(coef.into())
153+
.ok_or(PriceError::Overflow)?,
151154
};
152-
let value: i64 = value.try_into().map_err(|_| PriceError::Overflow)?;
153-
Self::from_mantissa(value).map_err(|_| PriceError::ZeroPriceUnsupported)
155+
let result_mantissa: i64 = result_mantissa
156+
.try_into()
157+
.map_err(|_| PriceError::Overflow)?;
158+
Self::from_mantissa(result_mantissa).map_err(|_| PriceError::ZeroPriceUnsupported)
154159
}
155160
}

lazer/sdk/rust/protocol/src/price/tests.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,15 +105,15 @@ fn price_ops() {
105105
let price2 = Price::parse_str("23.45", -8).unwrap();
106106
assert_float_absolute_eq!(
107107
price1
108-
.add_with_same_mantissa(price2)
108+
.add_with_same_exponent(price2)
109109
.unwrap()
110110
.to_f64(-8)
111111
.unwrap(),
112112
12.34 + 23.45
113113
);
114114
assert_float_absolute_eq!(
115115
price1
116-
.sub_with_same_mantissa(price2)
116+
.sub_with_same_exponent(price2)
117117
.unwrap()
118118
.to_f64(-8)
119119
.unwrap(),
@@ -133,6 +133,10 @@ fn price_ops() {
133133
12.34 * 34.56
134134
);
135135

136+
assert_eq!(
137+
price1.mul_decimal(34, 2).unwrap().mantissa_i64(),
138+
1234000000 * 3400
139+
);
136140
let price2 = Price::parse_str("42_000", 3).unwrap();
137141
assert_float_absolute_eq!(
138142
price2.mul_integer(2).unwrap().to_f64(3).unwrap(),

lazer/sdk/rust/protocol/src/rate.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,28 +24,28 @@ pub struct Rate(i64);
2424

2525
impl Rate {
2626
pub fn from_integer(value: i64, exponent: i16) -> Result<Self, RateError> {
27-
let value = match ExponentFactor::get(exponent).ok_or(RateError::Overflow)? {
27+
let mantissa = match ExponentFactor::get(exponent).ok_or(RateError::Overflow)? {
2828
ExponentFactor::Mul(coef) => value.checked_mul(coef).ok_or(RateError::Overflow)?,
2929
ExponentFactor::Div(coef) => value.checked_div(coef).ok_or(RateError::Overflow)?,
3030
};
31-
Ok(Self(value))
31+
Ok(Self(mantissa))
3232
}
3333

3434
pub fn parse_str(value: &str, exponent: i16) -> Result<Self, RateError> {
3535
let value: Decimal = value.parse()?;
36-
let value = match ExponentFactor::get(exponent).ok_or(RateError::Overflow)? {
36+
let mantissa = match ExponentFactor::get(exponent).ok_or(RateError::Overflow)? {
3737
ExponentFactor::Mul(coef) => value
3838
.checked_mul(Decimal::from_i64(coef).ok_or(RateError::Overflow)?)
3939
.ok_or(RateError::Overflow)?,
4040
ExponentFactor::Div(coef) => value
4141
.checked_div(Decimal::from_i64(coef).ok_or(RateError::Overflow)?)
4242
.ok_or(RateError::Overflow)?,
4343
};
44-
if !value.is_integer() {
44+
if !mantissa.is_integer() {
4545
return Err(RateError::TooPrecise);
4646
}
47-
let value: i64 = value.try_into().map_err(|_| RateError::Overflow)?;
48-
Ok(Self(value))
47+
let mantissa: i64 = mantissa.try_into().map_err(|_| RateError::Overflow)?;
48+
Ok(Self(mantissa))
4949
}
5050

5151
pub const fn from_mantissa(mantissa: i64) -> Self {
@@ -54,16 +54,16 @@ impl Rate {
5454

5555
pub fn from_f64(value: f64, exponent: i16) -> Result<Self, RateError> {
5656
let value = Decimal::from_f64(value).ok_or(RateError::Overflow)?;
57-
let value = match ExponentFactor::get(exponent).ok_or(RateError::Overflow)? {
57+
let mantissa = match ExponentFactor::get(exponent).ok_or(RateError::Overflow)? {
5858
ExponentFactor::Mul(coef) => value
5959
.checked_mul(Decimal::from_i64(coef).ok_or(RateError::Overflow)?)
6060
.ok_or(RateError::Overflow)?,
6161
ExponentFactor::Div(coef) => value
6262
.checked_div(Decimal::from_i64(coef).ok_or(RateError::Overflow)?)
6363
.ok_or(RateError::Overflow)?,
6464
};
65-
let value: i64 = value.try_into().map_err(|_| RateError::Overflow)?;
66-
Ok(Self(value))
65+
let mantissa: i64 = mantissa.try_into().map_err(|_| RateError::Overflow)?;
66+
Ok(Self(mantissa))
6767
}
6868

6969
pub fn mantissa(self) -> i64 {
@@ -72,7 +72,7 @@ impl Rate {
7272

7373
pub fn to_f64(self, exponent: i16) -> Result<f64, RateError> {
7474
match ExponentFactor::get(exponent).ok_or(RateError::Overflow)? {
75-
// Mul/div is reversed for this conversion
75+
// Mul/div is reversed for converting mantissa to value
7676
ExponentFactor::Mul(coef) => Ok(self.0 as f64 / coef as f64),
7777
ExponentFactor::Div(coef) => Ok(self.0 as f64 * coef as f64),
7878
}

0 commit comments

Comments
 (0)