Skip to content

Commit 884673a

Browse files
committed
Require second arg on prepare_add / prepare_sub, which can be 0 or None
1 parent 6bdef52 commit 884673a

File tree

1 file changed

+27
-39
lines changed

1 file changed

+27
-39
lines changed

packages/sync/src/range.rs

Lines changed: 27 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -129,16 +129,13 @@ where
129129
}
130130

131131
/// This is to be called at the beginning of a transaction, to reserve the ability to commit (or rollback) an addition.
132-
/// It doesn't enforce any maximum value. Use `prepare_add_max` for that.
133-
pub fn prepare_add(&mut self, value: T) -> Result<(), RangeError> {
134-
self.1 = self.1 + value;
135-
Ok(())
136-
}
137-
138-
/// This should be used instead of prepare_add if we wish to enforce a maximum value
139-
pub fn prepare_add_max(&mut self, value: T, max: T) -> Result<(), RangeError> {
140-
if self.1 + value > max {
141-
return Err(RangeError::Overflow);
132+
/// If the last value is set, it enforces that the new maximum will remain under that limit.
133+
/// Usage: `range.prepare_add(20, None)?;` or `range.prepare_add(20, 100)?;`
134+
pub fn prepare_add(&mut self, value: T, max: impl Into<Option<T>>) -> Result<(), RangeError> {
135+
if let Some(max) = max.into() {
136+
if self.1 + value > max {
137+
return Err(RangeError::Overflow);
138+
}
142139
}
143140
self.1 = self.1 + value;
144141
Ok(())
@@ -158,24 +155,13 @@ where
158155
self.assert_valid_range();
159156
}
160157

161-
/// This is to be called at the beginning of a transaction, to reserve the ability to commit (or rollback) a subtraction.
162-
/// It assumes we are enforcing a minimum value of 0. If you want a different minimum, use `prepare_sub_min`
163-
pub fn prepare_sub(&mut self, value: T) -> Result<(), RangeError> {
164-
if self.0 < value {
165-
return Err(RangeError::Underflow);
166-
}
167-
self.0 = self.0 - value;
168-
Ok(())
169-
}
170-
171-
/// This is to be called at the beginning of a transaction, to reserve the ability to commit (or rollback) a subtraction.
172-
/// You can specify a minimum value that the range must never go below. If you pass `None`, it will not even enforce
173-
/// a minimum of 0.
174-
pub fn prepare_sub_min(
175-
&mut self,
176-
value: T,
177-
min: impl Into<Option<T>>,
178-
) -> Result<(), RangeError> {
158+
/// This is to be called at the beginning of a transaction, to reserve the ability to commit
159+
/// (or rollback) a subtraction.
160+
/// You can specify a minimum value that the range must never go below, which is enforced here.
161+
/// No minimum: `range.prepare_sub(20, None)?;`
162+
/// Minimum of 0 (for uints): `range.prepare_sub(20, 0)?;`
163+
/// Higher minimum : `range.prepare_sub(20, 100)?;`
164+
pub fn prepare_sub(&mut self, value: T, min: impl Into<Option<T>>) -> Result<(), RangeError> {
179165
if let Some(min) = min.into() {
180166
// use plus not minus here, as we are much more likely to have underflow on u64 or Uint128 than overflow
181167
if self.0 < min + value {
@@ -241,7 +227,7 @@ mod tests {
241227
assert!(range.is_over_min(49));
242228

243229
// make a range (50, 80), it should compare properly to those outside the range
244-
range.prepare_add(30).unwrap();
230+
range.prepare_add(30, None).unwrap();
245231
assert!(!range.is_under_max(49));
246232
assert!(range.is_over_min(49));
247233
assert!(range.is_under_max(81));
@@ -256,11 +242,11 @@ mod tests {
256242
fn add_ranges() {
257243
// (80, 120)
258244
let mut range = ValueRange::new(80);
259-
range.prepare_add(40).unwrap();
245+
range.prepare_add(40, None).unwrap();
260246

261247
// (100, 200)
262248
let mut other = ValueRange::new(200);
263-
other.prepare_sub(100).unwrap();
249+
other.prepare_sub(100, 0).unwrap();
264250

265251
let total = range + other;
266252
assert_eq!(total, ValueRange(180, 320));
@@ -305,11 +291,13 @@ mod tests {
305291
fn works_with_uint128() {
306292
// (80, 120)
307293
let mut range = ValueRange::new(Uint128::new(80));
308-
range.prepare_add(Uint128::new(40)).unwrap();
294+
range.prepare_add(Uint128::new(40), None).unwrap();
309295

310296
// (100, 200)
311297
let mut other = ValueRange::new(Uint128::new(200));
312-
other.prepare_sub(Uint128::new(100)).unwrap();
298+
other
299+
.prepare_sub(Uint128::new(100), Uint128::zero())
300+
.unwrap();
313301

314302
let total = range + other;
315303
assert_eq!(total, ValueRange(Uint128::new(180), Uint128::new(320)));
@@ -327,11 +315,11 @@ mod tests {
327315
let mut lien = ValueRange::new(0u64);
328316

329317
// prepare some lien
330-
lien.prepare_add_max(2_000, collateral).unwrap();
331-
lien.prepare_add_max(5_000, collateral).unwrap();
318+
lien.prepare_add(2_000, collateral).unwrap();
319+
lien.prepare_add(5_000, collateral).unwrap();
332320

333321
// cannot add too much
334-
let err = lien.prepare_add_max(3_500, collateral).unwrap_err();
322+
let err = lien.prepare_add(3_500, collateral).unwrap_err();
335323
assert_eq!(err, RangeError::Overflow);
336324

337325
// let's commit the second pending lien (only 2000 left)
@@ -346,15 +334,15 @@ mod tests {
346334
collateral -= 2_000;
347335

348336
// start unbonding 3_000
349-
lien.prepare_sub(3_000).unwrap();
337+
lien.prepare_sub(3_000, 0).unwrap();
350338
// still; cannot increase max (7_000) over the new cap of 8_000
351-
let err = lien.prepare_add_max(1_500, collateral).unwrap_err();
339+
let err = lien.prepare_add(1_500, collateral).unwrap_err();
352340
assert_eq!(err, RangeError::Overflow);
353341

354342
// if we rollback the other pending lien, this works
355343
lien.rollback_add(2_000);
356344
assert_eq!(lien, ValueRange(2_000, 5_000));
357-
lien.prepare_add_max(1_500, collateral).unwrap();
345+
lien.prepare_add(1_500, collateral).unwrap();
358346
}
359347

360348
// idea here is to model the liens as in vault, and ensure we can calculate aggregates over them properly

0 commit comments

Comments
 (0)