Skip to content

Commit

Permalink
fix!(core): Handle unreserve of already unreserved slots (#3867)
Browse files Browse the repository at this point in the history
  • Loading branch information
breathx authored Apr 5, 2024
1 parent 7d21c84 commit db829e3
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 6 deletions.
42 changes: 36 additions & 6 deletions core/src/reservation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,14 +201,20 @@ impl GasReserver {
/// 2. Reservation was "unreserved", so in [`GasReservationState::Removed`] state.
/// 3. Reservation was marked used.
pub fn unreserve(&mut self, id: ReservationId) -> Result<u64, ReservationError> {
// Docs error case #1.
let state = self
.states
.get(&id)
.ok_or(ReservationError::InvalidReservationId)?;

if let GasReservationState::Exists { used: true, .. }
| GasReservationState::Created { used: true, .. } = state
{
if matches!(
state,
// Docs error case #2.
GasReservationState::Removed { .. } |
// Docs error case #3.
GasReservationState::Exists { used: true, .. } |
GasReservationState::Created { used: true, .. }
) {
return Err(ReservationError::InvalidReservationId);
}

Expand All @@ -221,9 +227,7 @@ impl GasReserver {
amount
}
GasReservationState::Created { amount, .. } => amount,
GasReservationState::Removed { .. } => {
return Err(ReservationError::InvalidReservationId);
}
GasReservationState::Removed { .. } => unreachable!("Checked above"),
};

Ok(amount)
Expand Down Expand Up @@ -485,4 +489,30 @@ mod tests {
Err(ReservationError::InvalidReservationId)
);
}

#[test]
fn unreserving_unreserved() {
let id = ReservationId::from([0xff; 32]);
let slot = GasReservationSlot {
amount: 1,
start: 2,
finish: 3,
};

let mut map = GasReservationMap::new();
map.insert(id, slot.clone());

let mut reserver = GasReserver::new(&Default::default(), map, 256);

let amount = reserver.unreserve(id).expect("Shouldn't fail");
assert_eq!(amount, slot.amount);

assert!(reserver.unreserve(id).is_err());
assert_eq!(
reserver.states().get(&id).cloned(),
Some(GasReservationState::Removed {
expiration: slot.finish
})
);
}
}
Binary file not shown.
8 changes: 8 additions & 0 deletions utils/runtime-fuzzer/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ fn test_corpus_c6e2a597aebabecc9bbb11eefdaa4dd8a6770188() {
assert!(run_impl(FuzzerInput::new(input)).is_ok());
}

#[test]
fn test_corpus_aa91f1d5873e3fa7045ceeef9e26448e71f82482() {
gear_utils::init_default_logger();

let input = include_bytes!("../fuzz_corpus/aa91f1d5873e3fa7045ceeef9e26448e71f82482");
assert!(run_impl(FuzzerInput::new(input)).is_ok());
}

proptest! {
#![proptest_config(ProptestConfig::with_cases(10))]
#[test]
Expand Down

0 comments on commit db829e3

Please sign in to comment.