{"record":{"id":"52af1c73f723405c","repo":"datahaven-xyz/datahaven","slug":"halted-52af1c","errorCode":"Halted","errorMessage":"Halted","messagePattern":"Halted","errorType":"error_code","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"operator/pallets/inbound-queue-v2/src/lib.rs","lineNumber":192,"sourceCode":"    }\n\n    /// StorageMap used for encoding a SparseBitmapImpl that tracks whether a specific nonce has\n    /// been processed or not. Message nonces are unique and never repeated.\n    #[pallet::storage]\n    pub type NonceBitmap<T: Config> = StorageMap<_, Twox64Concat, u128, u128, ValueQuery>;\n\n    /// The current operating mode of the pallet.\n    #[pallet::storage]\n    pub type OperatingMode<T: Config> = StorageValue<_, BasicOperatingMode, ValueQuery>;\n\n    #[pallet::call]\n    impl<T: Config> Pallet<T> {\n        /// Submit an inbound message originating from the Gateway contract on Ethereum\n        #[pallet::call_index(0)]\n        #[pallet::weight(T::WeightInfo::submit())]\n        pub fn submit(origin: OriginFor<T>, event: Box<EventProof>) -> DispatchResult {\n            let who = ensure_signed(origin)?;\n            ensure!(!OperatingMode::<T>::get().is_halted(), Error::<T>::Halted);\n\n            // submit message for verification\n            T::Verifier::verify(&event.event_log, &event.proof)\n                .map_err(|e| Error::<T>::Verification(e))?;\n\n            // Decode event log into a bridge message\n            let message =\n                Message::try_from(&event.event_log).map_err(|_| Error::<T>::InvalidMessage)?;\n\n            Self::process_message(who, message)\n        }\n\n        /// Halt or resume all pallet operations. May only be called by root.\n        #[pallet::call_index(1)]\n        #[pallet::weight((T::DbWeight::get().reads_writes(1, 1), DispatchClass::Operational))]\n        pub fn set_operating_mode(\n            origin: OriginFor<T>,\n            mode: BasicOperatingMode,","sourceCodeStart":174,"sourceCodeEnd":210,"githubUrl":"https://github.com/datahaven-xyz/datahaven/blob/edcb13dbbcd3c29489eaa2480a6f60ee4cb1f3ec/operator/pallets/inbound-queue-v2/src/lib.rs#L174-L210","documentation":"The inbound-queue-v2 pallet's `submit` extrinsic throws `Error::Halted` when the pallet's `OperatingMode` storage value reports `is_halted()`. The pallet is placed in halted mode (normally via governance/maintenance) to stop accepting new inbound Ethereum messages, e.g. during upgrades or incident response. Any submission attempt is rejected before verification even runs.","triggerScenarios":"Calling the `submit` extrinsic (call_index 0) with a signed origin while `OperatingMode::<T>::get().is_halted()` is true — i.e. the bridge pallet is in Normal→Halted state set by an operational/governance call.","commonSituations":"Bridging during scheduled maintenance windows or after an incident when operators halt the inbound queue; running E2E tests against a runtime configured to start halted; relayers retrying message submission while the pallet remains halted after a runtime upgrade.","solutions":["Check the pallet operating mode (query `inboundQueueV2OperatingMode` / OperatingMode storage) before submitting; wait until it is `Normal`.","If maintenance is over, the appropriate governance/ops channel must call the extrinsic that sets OperatingMode back to Normal.","If halting was unexpected, inspect recent runtime-upgrade or governance activity to find who/what halted the queue.","In tests, configure the mock/runtime genesis so OperatingMode starts as Normal."],"exampleFix":"// before: submit fails with Halted\nlet _ = InboundQueueV2::submit(RuntimeOrigin::signed(relayer), Box::new(event_proof));\n\n// after: ensure the pallet is not halted first\nassert!(!OperatingMode::<Runtime>::get().is_halted(), \"bridge halted; retry later\");\nInboundQueueV2::submit(RuntimeOrigin::signed(relayer), Box::new(event_proof))?;","handlingStrategy":"validation","validationCode":"let mode = api.query.inboundQueueV2.operatingMode();\nif (mode.isHalted) throw new Error('Bridge halted; hold submissions');","typeGuard":"function isOperational(mode) { return mode != null && mode.type === 'Normal'; }","tryCatchPattern":"try { await api.tx.inboundQueueV2.submit(eventProof).signAndSend(account); } catch (e) { if (String(e).includes('Halted')) scheduleRetryAfterMaintenance(); else throw e; }","preventionTips":["Query OperatingMode before every submit","Subscribe to maintenance/governance announcements","Retry with backoff during known halt windows","Configure test runtimes to start in Normal mode"],"tags":["substrate","bridge","pallet","operating-mode","maintenance"],"backgroundTag":"feature-not-enabled","analyzedSha":"edcb13dbbcd3c29489eaa2480a6f60ee4cb1f3ec","analyzedAt":"2026-09-13T19:19:32.206Z","contentChangedAt":"2026-09-13T19:19:32.206Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}