use crate::helpers::event::{GlobalLockAcquired, GlobalLockReleased}; use crate::*; use near_sdk::env; #[near] impl Contract { /// Get the current lock status - returns the account holding the lock, or None pub fn get_lock_status(&self) -> Option { self.kernel_state.global_lock_holder.clone() } } impl Contract { /// Acquire the global contract lock pub fn internal_acquire_lock(&mut self) { require!( self.kernel_state.global_lock_holder.is_none(), format!( "Global lock is already held by {}. Cannot acquire lock.", self.kernel_state.global_lock_holder.as_ref().unwrap() ) ); let caller = env::predecessor_account_id(); GlobalLockAcquired { holder: &caller }.emit(); self.kernel_state.global_lock_holder = Some(caller); } /// Release the global contract lock (only current lock holder can release) /// This will fail if there are pending actions that need to be completed pub fn internal_release_lock(&mut self) { let caller = env::predecessor_account_id(); // Validate that caller holds the lock self.internal_validate_lock_held(&caller); require!( self.can_release_lock(), "Cannot release lock: pending actions must be completed first. Use get_pending_actions() to view them." ); GlobalLockReleased { holder: &caller }.emit(); self.kernel_state.global_lock_holder = None; } /// Force release the global lock pub fn internal_force_release_lock(&mut self) { let previous_holder = self .kernel_state .global_lock_holder .take() .expect("No lock found"); // Emit global lock released event GlobalLockReleased { holder: &previous_holder, } .emit(); } /// Validate that the caller currently holds the global lock pub fn internal_validate_lock_held(&self, caller: &AccountId) { require!( self.kernel_state.global_lock_holder.is_some(), format!( "Global lock is required for this operation, but no lock is currently held. Caller: {}", caller ) ); require!( self.kernel_state.global_lock_holder.as_ref().unwrap() == caller, format!( "Global lock is required for this operation. Lock is currently held by {}, but caller is {}", self.kernel_state.global_lock_holder.as_ref().unwrap(), caller ) ); } }