pub use crate::traits::errors::ReentrancyGuardError;
use brush::{
declare_storage_trait,
modifier_definition,
};
pub use derive::ReentrancyGuardStorage;
use ink_storage::traits::push_spread_root;
pub const STORAGE_KEY: [u8; 32] = ink_lang::blake2x256!("brush::ReentrancyGuardData");
#[derive(Default, Debug)]
#[brush::storage(STORAGE_KEY)]
pub struct ReentrancyGuardData {
pub status: u8,
pub _reserved: Option<()>,
}
declare_storage_trait!(ReentrancyGuardStorage, ReentrancyGuardData);
const NOT_ENTERED: u8 = 0;
const ENTERED: u8 = 1;
#[modifier_definition]
pub fn non_reentrant<T, F, R, E>(instance: &mut T, body: F) -> Result<R, E>
where
T: ReentrancyGuardStorage,
F: FnOnce(&mut T) -> Result<R, E>,
E: From<ReentrancyGuardError>,
{
if instance.get().status == ENTERED {
return Err(From::from(ReentrancyGuardError::ReentrantCall))
}
instance.get_mut().status = ENTERED;
push_spread_root(instance.get(), &Default::default());
let result = body(instance);
instance.get_mut().status = NOT_ENTERED;
return result
}