Skip to content

Commit a405a56

Browse files
committed
program: use sparse matrix for constituent map and update tests
1 parent b2cf992 commit a405a56

File tree

2 files changed

+35
-35
lines changed

2 files changed

+35
-35
lines changed

programs/drift/src/state/lp_pool.rs

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -134,18 +134,24 @@ pub struct Constituent {
134134
// pub struct PerpConstituent {
135135
// }
136136

137+
pub struct AmmConstituentDatum {
138+
pub perp_market_index: u16,
139+
pub constituent_index: u16,
140+
/// PERCENTAGE_PRECISION. The weight this constituent has on the perp market
141+
pub data: u64,
142+
pub last_slot: u64,
143+
}
144+
137145
pub struct WeightDatum {
146+
pub constituent_index: u16,
147+
/// PERCENTAGE_PRECISION. The weights of the target weight matrix
138148
pub data: u64,
139149
pub last_slot: u64,
140150
}
141151

142152
pub struct AmmConstituentMapping {
143-
// rows in the matrix, (perp markets)
144-
pub num_rows: u16,
145-
// columns in the matrix (VaultConstituents, spot markets)
146-
pub num_cols: u16,
147153
// flattened matrix elements, PERCENTAGE_PRECISION. Keep at the end of the account to allow expansion with new constituents.
148-
pub data: Vec<WeightDatum>,
154+
pub data: Vec<AmmConstituentDatum>,
149155
}
150156

151157
pub struct ConstituentTargetWeights {
@@ -175,15 +181,13 @@ impl ConstituentTargetWeights {
175181
pub fn update_target_weights(
176182
&mut self,
177183
mapping: &AmmConstituentMapping,
178-
amm_inventory: &[u64], // length = mapping.num_rows
184+
amm_inventory: &[(u16, u64)], // length = mapping.num_rows
179185
constituents: &[Constituent],
180186
prices: &[u64], // same order as constituents
181187
aum: u64,
182188
slot: u64,
183189
) -> DriftResult<()> {
184190
// assert_ne!(aum, 0);
185-
assert_eq!(constituents.len(), mapping.num_cols as usize);
186-
assert_eq!(amm_inventory.len(), mapping.num_rows as usize);
187191
assert_eq!(prices.len(), constituents.len());
188192

189193
self.data.clear();
@@ -194,11 +198,13 @@ impl ConstituentTargetWeights {
194198
for (constituent_index, constituent) in constituents.iter().enumerate() {
195199
let mut target_amount = 0u128;
196200

197-
for (row_index, &inventory) in amm_inventory.iter().enumerate() {
198-
let idx = row_index * mapping.num_cols as usize + constituent_index;
201+
for (perp_market_index, inventory) in amm_inventory.iter() {
202+
let idx = mapping.data
203+
.iter()
204+
.position(|d| &d.perp_market_index == perp_market_index)
205+
.expect("missing mapping for this market index");
199206
let weight = mapping.data[idx].data as u128; // PERCENTAGE_PRECISION
200-
201-
target_amount += inventory as u128 * weight / PERCENTAGE_PRECISION_U64 as u128;
207+
target_amount += (*inventory) as u128 * weight / PERCENTAGE_PRECISION_U64 as u128;
202208
}
203209

204210
let price = prices[constituent_index] as u128;
@@ -210,6 +216,7 @@ impl ConstituentTargetWeights {
210216
let weight_datum = (target_weight as u64).min(PERCENTAGE_PRECISION_U64);
211217

212218
self.data.push(WeightDatum {
219+
constituent_index: constituent_index as u16,
213220
data: weight_datum,
214221
last_slot: slot,
215222
});

programs/drift/src/state/lp_pool/tests.rs

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,11 @@ mod tests {
88

99
const PERCENTAGE_PRECISION_U64: u64 = 1_000_000;
1010

11-
fn weight_datum(data: u64, last_slot: u64) -> WeightDatum {
12-
WeightDatum { data, last_slot }
11+
fn weight_datum(constituent_index: u16, data: u64, last_slot: u64) -> WeightDatum {
12+
WeightDatum { constituent_index, data, last_slot }
13+
}
14+
fn amm_const_datum(perp_market_index: u16, constituent_index: u16, data: u64, last_slot: u64) -> AmmConstituentDatum {
15+
AmmConstituentDatum { perp_market_index, constituent_index, data, last_slot }
1316
}
1417

1518
fn dummy_constituent(index: u16) -> Constituent {
@@ -37,12 +40,10 @@ mod tests {
3740
#[test]
3841
fn test_single_zero_weight() {
3942
let mapping = AmmConstituentMapping {
40-
num_rows: 1,
41-
num_cols: 1,
42-
data: vec![weight_datum(0, 0)],
43+
data: vec![amm_const_datum(0, 1, 0, 0)],
4344
};
4445

45-
let amm_inventory = vec![1_000_000];
46+
let amm_inventory: Vec<(u16, u64)> = vec![(0, 1_000_000)];
4647
let prices = vec![1_000_000];
4748
let constituents = vec![dummy_constituent(0)];
4849
let aum = 1_000_000;
@@ -68,12 +69,10 @@ mod tests {
6869
#[test]
6970
fn test_single_full_weight() {
7071
let mapping = AmmConstituentMapping {
71-
num_rows: 1,
72-
num_cols: 1,
73-
data: vec![weight_datum(PERCENTAGE_PRECISION_U64, 0)],
72+
data: vec![amm_const_datum(0, 1, PERCENTAGE_PRECISION_U64, 0)],
7473
};
7574

76-
let amm_inventory = vec![1_000_000];
75+
let amm_inventory = vec![(0, 1_000_000)];
7776
let prices = vec![1_000_000];
7877
let constituents = vec![dummy_constituent(0)];
7978
let aum = 1_000_000;
@@ -99,15 +98,13 @@ mod tests {
9998
#[test]
10099
fn test_multiple_constituents_partial_weights() {
101100
let mapping = AmmConstituentMapping {
102-
num_rows: 1,
103-
num_cols: 2,
104101
data: vec![
105-
weight_datum(PERCENTAGE_PRECISION_U64 / 2, 0),
106-
weight_datum(PERCENTAGE_PRECISION_U64 / 2, 0),
102+
amm_const_datum(0, 1, PERCENTAGE_PRECISION_U64 / 2, 0),
103+
amm_const_datum(0, 2, PERCENTAGE_PRECISION_U64 / 2, 0),
107104
],
108105
};
109106

110-
let amm_inventory = vec![1_000_000];
107+
let amm_inventory = vec![(0, 1_000_000)];
111108
let prices = vec![1_000_000, 1_000_000];
112109
let constituents = vec![dummy_constituent(0), dummy_constituent(1)];
113110
let aum = 1_000_000;
@@ -136,12 +133,10 @@ mod tests {
136133
#[test]
137134
fn test_zero_aum_safe() {
138135
let mapping = AmmConstituentMapping {
139-
num_rows: 1,
140-
num_cols: 1,
141-
data: vec![weight_datum(PERCENTAGE_PRECISION_U64, 0)],
136+
data: vec![amm_const_datum(0, 1, PERCENTAGE_PRECISION_U64, 0)],
142137
};
143138

144-
let amm_inventory = vec![1_000_000];
139+
let amm_inventory = vec![(0, 1_000_000)];
145140
let prices = vec![1_000_000];
146141
let constituents = vec![dummy_constituent(0)];
147142
let aum = 0;
@@ -167,12 +162,10 @@ mod tests {
167162
#[test]
168163
fn test_overflow_protection() {
169164
let mapping = AmmConstituentMapping {
170-
num_rows: 1,
171-
num_cols: 1,
172-
data: vec![weight_datum(u64::MAX, 0)],
165+
data: vec![amm_const_datum(0, 1, u64::MAX, 0)],
173166
};
174167

175-
let amm_inventory = vec![u64::MAX];
168+
let amm_inventory = vec![(0, u64::MAX)];
176169
let prices = vec![u64::MAX];
177170
let constituents = vec![dummy_constituent(0)];
178171
let aum = 1;

0 commit comments

Comments
 (0)