Skip to content

Commit 53c13d3

Browse files
Update governance commands to halt bridge (#1776)
* governance commands * halt improvements * fixes * Add Emergency Procedures docs page Adds the docs/resources/emergency-procedures.md file referenced by SUMMARY.md and governance-and-operational-processes.md in this PR, extending the on-call runbook with a Producing a halt-bridge preimage section that points to the live governance UI at app.snowbridge.network/governance alongside the snowbridge-preimage CLI. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Expand Emergency Procedures with incident runbook Adds the operational runbook sections around the existing halt-bridge command reference: Detection signals (including bug bounty reports and visibly drained funds), Decision authority (solo halt only for visible exploits, otherwise 2/3 confirm to avoid spooking the community with a halt referendum), Comms during an incident (Slack first, then Element with Parity, then affected integrators, no public comms until fix is deployed), Submitting the preimage (Whitelisted Caller flow with Fellowship-whitelist timing), Verifying the halt (per-flag storage queries with Gateway-side caveat), Resuming the bridge (governance UI is the only practical path), and Post-mortem (Google Doc, 48h SLA). Also reframes the Producing a halt-bridge preimage and Resuming the bridge sections to make app.snowbridge.network/governance the primary path, with the snowbridge-preimage CLI as a fallback only. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Iterate Emergency Procedures based on team feedback - Detection: trim to drained funds + verified-PoC bug bounty (HackenProof or direct); drop generic anomaly bullets. - Decision authority: distinguish solo halt (visible exploit, funds draining) from confirmed halt (2 team members agree) to avoid spooking the community with a halt referendum for a maybe-incident. Remove team-size denominators so the doc survives team-size changes. - Comms: name the #snowbridge-security Slack channel and Telegram as the integrator channel. - Halt path: governance page is primary; SDK (buildHaltBridgePreimage / buildResumeBridgePreimage) is the fallback. Drop snowbridge-preimage CLI from the runbook. - Submission: document the actual opengov-cli flow: Asset Hub batch (preimage note + public referendum, anyone) and Collectives Chain batch (Fellowship whitelist, rank-3+ Fellow only). Include the enactment-time default caveat. - Rename Emergency Pause to Halt scopes reference; rewrite scope list and failure-mode + verification tables to use UI form-field names instead of CLI flag names. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Tighten Emergency Procedures and lead with halt mechanics Restructure so halt-action sections (Producing, Halt scopes reference, Submitting, Verifying) sit directly under the intro for fast access under pressure; Detection, Decision authority, and Comms move below. Trim prose throughout: intro 2 paragraphs to 2 lines, scope bullets compressed to one sentence each, Decision authority converted to a table, numbered comms steps shortened. Protocol-relevant details (pallet names, V1/V2 distinctions, relayer-delivery caveats) kept; explanatory framing cut. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Add buildHaltBridgeSubmissionUrls to governance SDK Lets the snowbridge-app governance UI emit two papi.how submission links directly from a halt-bridge preimage, replacing the operator's manual opengov-cli + Rust toolchain step: 1. Asset Hub batch URL: utility.forceBatch([preimage.notePreimage( dispatchWhitelistedCallWithPreimage(call)), referenda.submit( Origins(WhitelistedCaller), Lookup{hash, len}, After(n))]). Anyone on the operator team can submit. 2. Collectives Fellowship URL: utility.forceBatch([fellowshipReferenda .submit(FellowshipOrigins(Fellows), Inline(polkadotXcm.send to Asset Hub carrying Transact(whitelist.whitelistCall(preimageHash))), After(10))]). Must be submitted by a rank-3+ Fellow. Mirrors joepetrowski/opengov-cli's polkadot_fellowship_referenda flow (src/submit_referendum.rs ~L628-L811). Includes opengov_submission_check.ts under @snowbridge/operations as a hex-parity check against a recorded opengov-cli fixture, currently passes byte-for-byte on the live Polkadot Asset Hub + Collectives runtimes. resumeBridgeSubmissionUrls is a thin alias because the wire format is identical; both halt and resume preimages go through the same WhitelistedCaller track. UI changes (copy-preimage button, submit-to-AH button, copy-Fellowship- URL button in HaltBridgeForm.tsx) are intentionally out of scope and will follow in snowbridge-app. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Reframe halt-bridge submission docs around governance UI The governance page at app.snowbridge.network/governance now emits both the preimage AND the two papi.how submission links directly (Asset Hub batch + Fellowship whitelist), via the new buildHaltBridgeSubmissionUrls SDK helper. Reflect that as the primary path: - "Producing a halt-bridge preimage" -> "Producing the preimage and submission links": one step now, the page emits the URLs along with the preimage. - "Submitting the preimage" -> "Submitting": leads with "click Open on AH batch / Copy Fellowship link from the UI", no intermediate tooling. - Resuming section mirrors halt: UI emits both. - opengov-cli demoted to a fallback subsection under Submitting, for the case where the UI is unreachable. - SDK fallbacks updated to include buildHalt/ResumeBridgeSubmissionUrls alongside the preimage builders. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore: refresh PR head (no-op) --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent f7b06cb commit 53c13d3

11 files changed

Lines changed: 772 additions & 71 deletions

File tree

control/preimage/src/commands.rs

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,16 @@ use crate::bridge_hub_runtime::runtime_types::{
2424
},
2525
snowbridge_outbound_queue_primitives::{v1::message::Initializer, OperatingMode},
2626
snowbridge_pallet_ethereum_client, snowbridge_pallet_inbound_queue,
27-
snowbridge_pallet_outbound_queue, snowbridge_pallet_system,
27+
snowbridge_pallet_inbound_queue_v2, snowbridge_pallet_outbound_queue,
28+
snowbridge_pallet_system, snowbridge_pallet_system_v2,
2829
};
2930
use crate::bridge_hub_runtime::RuntimeCall as BridgeHubRuntimeCall;
3031

32+
use crate::asset_hub_runtime::runtime_types::{
33+
snowbridge_core::operating_mode::BasicOperatingMode as AssetHubBasicOperatingMode,
34+
snowbridge_pallet_system_frontend,
35+
};
36+
3137
#[cfg(feature = "polkadot")]
3238
pub mod asset_hub_polkadot_types {
3339
pub use crate::asset_hub_runtime::runtime_types::staging_xcm::v5::{
@@ -150,6 +156,51 @@ pub fn outbound_queue_operating_mode(param: &OperatingModeEnum) -> BridgeHubRunt
150156
)
151157
}
152158

159+
// V2 variant: halts the inbound-queue-v2 pallet's `submit` extrinsic, blocking
160+
// processing of V2 Ethereum -> Polkadot messages on BridgeHub.
161+
pub fn inbound_queue_v2_operating_mode(param: &OperatingModeEnum) -> BridgeHubRuntimeCall {
162+
let mode = match param {
163+
OperatingModeEnum::Normal => BasicOperatingMode::Normal,
164+
OperatingModeEnum::Halted => BasicOperatingMode::Halted,
165+
};
166+
BridgeHubRuntimeCall::EthereumInboundQueueV2(
167+
snowbridge_pallet_inbound_queue_v2::pallet::Call::set_operating_mode { mode },
168+
)
169+
}
170+
171+
// V2 variant: sends `Command::SetOperatingMode` to the Gateway via the V2 outbound
172+
// queue. Sets the same Gateway `$.mode` storage as the V1 variant; both are kept
173+
// so governance can halt via whichever outbound path is live.
174+
pub fn gateway_operating_mode_v2(
175+
operating_mode: &GatewayOperatingModeEnum,
176+
) -> BridgeHubRuntimeCall {
177+
let mode = match operating_mode {
178+
GatewayOperatingModeEnum::Normal => OperatingMode::Normal,
179+
GatewayOperatingModeEnum::RejectingOutboundMessages => {
180+
OperatingMode::RejectingOutboundMessages
181+
}
182+
};
183+
BridgeHubRuntimeCall::EthereumSystemV2(
184+
snowbridge_pallet_system_v2::pallet::Call::set_operating_mode { mode },
185+
)
186+
}
187+
188+
// AssetHub-side: halts the system-frontend pallet. The `PausableExporter` wrapping
189+
// the AssetHub->Ethereum XcmRouter consults `SnowbridgeSystemFrontend::is_paused()`
190+
// and returns `SendError::NotApplicable` when halted, short-circuiting every
191+
// AssetHub->Ethereum export (V1 and V2 share the same wrapper). This is the
192+
// primary outbound halt lever for V2 because `outbound-queue-v2` has no local
193+
// operating-mode storage.
194+
pub fn system_frontend_operating_mode(param: &OperatingModeEnum) -> AssetHubRuntimeCall {
195+
let mode = match param {
196+
OperatingModeEnum::Normal => AssetHubBasicOperatingMode::Normal,
197+
OperatingModeEnum::Halted => AssetHubBasicOperatingMode::Halted,
198+
};
199+
AssetHubRuntimeCall::SnowbridgeSystemFrontend(
200+
snowbridge_pallet_system_frontend::pallet::Call::set_operating_mode { mode },
201+
)
202+
}
203+
153204
pub fn upgrade(params: &UpgradeArgs) -> BridgeHubRuntimeCall {
154205
BridgeHubRuntimeCall::EthereumSystem(snowbridge_pallet_system::pallet::Call::upgrade {
155206
impl_address: params.logic_address.into_array().into(),

control/preimage/src/helpers.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,12 +134,35 @@ pub async fn query_weight_asset_hub(
134134
Ok((call_info.weight.ref_time, call_info.weight.proof_size))
135135
}
136136

137-
pub fn utility_force_batch(calls: Vec<AssetHubRuntimeCall>) -> AssetHubRuntimeCall {
137+
/// Emits `pallet_utility::Call::batch_all`, which rolls back every call if any one
138+
/// fails. The default for governance batches that must commit atomically.
139+
pub fn utility_batch_all(calls: Vec<AssetHubRuntimeCall>) -> AssetHubRuntimeCall {
138140
AssetHubRuntimeCall::Utility(
139141
crate::asset_hub_runtime::runtime_types::pallet_utility::pallet::Call::batch_all { calls },
140142
)
141143
}
142144

145+
/// Emits `pallet_utility::Call::batch`, which short-circuits on the first failing call
146+
/// but commits all preceding calls.
147+
#[allow(dead_code)]
148+
pub fn utility_batch(calls: Vec<AssetHubRuntimeCall>) -> AssetHubRuntimeCall {
149+
AssetHubRuntimeCall::Utility(
150+
crate::asset_hub_runtime::runtime_types::pallet_utility::pallet::Call::batch { calls },
151+
)
152+
}
153+
154+
/// Emits `pallet_utility::Call::force_batch`, which attempts every call regardless of
155+
/// failures and reports per-call results via `ItemFailed` events. Use when each call
156+
/// must fire independently — e.g. the halt-bridge preimage, where one stuck lever
157+
/// (e.g. HRMP transport failure for the BH XCM) should not skip the rest.
158+
pub fn utility_force_batch(calls: Vec<AssetHubRuntimeCall>) -> AssetHubRuntimeCall {
159+
AssetHubRuntimeCall::Utility(
160+
crate::asset_hub_runtime::runtime_types::pallet_utility::pallet::Call::force_batch {
161+
calls,
162+
},
163+
)
164+
}
165+
143166
#[cfg(any(feature = "westend", feature = "paseo"))]
144167
pub fn sudo(call: Box<AssetHubRuntimeCall>) -> AssetHubRuntimeCall {
145168
return AssetHubRuntimeCall::Sudo(

control/preimage/src/main.rs

Lines changed: 117 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ use alloy_primitives::{address, utils::parse_units, Address, Bytes, FixedBytes,
1111
use clap::{Args, Parser, Subcommand, ValueEnum};
1212
use codec::Encode;
1313
use constants::{ASSET_HUB_API, BRIDGE_HUB_API, POLKADOT_DECIMALS, POLKADOT_SYMBOL, RELAY_API};
14-
use helpers::{force_xcm_version, send_xcm_asset_hub, send_xcm_bridge_hub, utility_force_batch};
14+
use helpers::{
15+
force_xcm_version, send_xcm_asset_hub, send_xcm_bridge_hub, utility_batch_all,
16+
utility_force_batch,
17+
};
1518
use snowbridge_preimage_chopsticks::generate_chopsticks_script;
1619
use sp_crypto_hashing::blake2_256;
1720
use std::{io::Write, path::PathBuf};
@@ -204,24 +207,63 @@ pub struct PricingParametersArgs {
204207

205208
#[derive(Debug, Args)]
206209
pub struct HaltBridgeArgs {
207-
/// Halt the Ethereum gateway, blocking message from Ethereum to Polkadot in the Ethereum
208-
/// contract.
210+
/// Halt the Ethereum Gateway contract (both V1 and V2 paths). Sends
211+
/// `Command::SetOperatingMode(Halted)` via both V1 and V2 system pallets so the halt
212+
/// is delivered via whichever outbound queue is live. Once processed on Ethereum,
213+
/// this blocks `v2_sendMessage`, `v2_registerToken`, and V1 `sendToken`/`sendMessage`
214+
/// on the Gateway. Delivery is relayer-dependent.
209215
#[arg(long, value_name = "HALT_GATEWAY")]
210216
gateway: bool,
211-
/// Halt the Ethereum Inbound Queue, blocking messages from BH to AH.
217+
/// V2-only Gateway halt: sends `Command::SetOperatingMode(Halted)` only via the V2
218+
/// system pallet. Blocks `v2_sendMessage` and `v2_registerToken` on the Gateway once
219+
/// the message is delivered to Ethereum. Leaves V1 `sendToken`/`sendMessage` working.
220+
#[arg(long, value_name = "HALT_GATEWAY_V2")]
221+
gateway_v2: bool,
222+
/// Halt both V1 and V2 inbound-queue pallets on BridgeHub, blocking processing of
223+
/// Ethereum -> Polkadot messages. For surgical halts of a single version, use
224+
/// `--inbound-queue-v1` or `--inbound-queue-v2`.
212225
#[arg(long, value_name = "HALT_INBOUND_QUEUE")]
213226
inbound_queue: bool,
214-
/// Halt the Ethereum Outbound Queue, blocking message from AH to BH.
227+
/// Halt only the V1 inbound-queue pallet on BridgeHub.
228+
#[arg(long, value_name = "HALT_INBOUND_QUEUE_V1")]
229+
inbound_queue_v1: bool,
230+
/// Halt only the V2 inbound-queue pallet on BridgeHub.
231+
#[arg(long, value_name = "HALT_INBOUND_QUEUE_V2")]
232+
inbound_queue_v2: bool,
233+
/// Halt AssetHub -> Ethereum outbound traffic. Halts the V1 outbound-queue pallet
234+
/// on BridgeHub AND the system-frontend pallet on AssetHub; the latter short-circuits
235+
/// the AssetHub->Ethereum `PausableExporter` for both V1 and V2 at the XcmRouter
236+
/// layer (V2's `outbound-queue-v2` has no local halt, so the frontend halt is the
237+
/// primary V2 outbound lever).
215238
#[arg(long, value_name = "HALT_OUTBOUND_QUEUE")]
216239
outbound_queue: bool,
217-
/// Halt the Ethereum client, blocking consensus updates to the light client.
240+
/// Router-layer P->E halt: halts only the AssetHub system-frontend pallet. Blocks
241+
/// BOTH V1 and V2 P->E at the `PausableExporter`, returning `SendError::NotApplicable`
242+
/// to the XcmRouter. The V1 BridgeHub outbound-queue is left untouched so it keeps
243+
/// draining in-flight V1 messages already enqueued there. There is no V2-only
244+
/// operating-mode halt for P->E; for a V2-only deterrent use `--assethub-max-fee-v2`.
245+
#[arg(long, value_name = "HALT_SYSTEM_FRONTEND")]
246+
system_frontend: bool,
247+
/// Halt the Ethereum beacon light client, blocking new beacon-header ingestion.
248+
/// Note: this does NOT propagate into the `Verifier::verify` trait impl that
249+
/// downstream consumers (`inbound-queue(-v2)::submit`,
250+
/// `outbound-queue-v2::submit_delivery_receipt`) call — those verify against
251+
/// already-stored finalised state. Halt those consumers individually to block
252+
/// proof-consuming flows during a suspected beacon compromise.
218253
#[arg(long, value_name = "HALT_ETHEREUM_CLIENT")]
219254
ethereum_client: bool,
220-
/// Set the AH to Ethereum fee to a high amount, effectively blocking messages from AH ->
221-
/// Ethereum.
255+
/// Set the AssetHub -> Ethereum outbound fee to `u128::MAX` for both V1
256+
/// (`BridgeHubEthereumBaseFee`) and V2 (`BridgeHubEthereumBaseFeeV2`) storage
257+
/// items, effectively deterring user sends via fee pricing. Complementary to the
258+
/// system-frontend halt; does not block at the router layer.
222259
#[arg(long, value_name = "ASSETHUB_MAX_FEE")]
223260
assethub_max_fee: bool,
224-
/// Halt all parts of the bridge
261+
/// V2-only variant of `--assethub-max-fee`: writes only the
262+
/// `BridgeHubEthereumBaseFeeV2` storage item, leaving V1 fee unchanged.
263+
/// Use this to deter V2 P->E sends while V1 traffic continues unimpeded.
264+
#[arg(long, value_name = "ASSETHUB_MAX_FEE_V2")]
265+
assethub_max_fee_v2: bool,
266+
/// Halt all parts of the bridge (equivalent to passing every other flag).
225267
#[arg(long, value_name = "HALT_SNOWBRIDGE")]
226268
all: bool,
227269
}
@@ -384,7 +426,7 @@ async fn run() -> Result<(), Box<dyn std::error::Error>> {
384426
],
385427
)
386428
.await?;
387-
utility_force_batch(vec![bridge_hub_call, asset_hub_call])
429+
utility_batch_all(vec![bridge_hub_call, asset_hub_call])
388430
}
389431
Command::UpdateAsset(params) => {
390432
send_xcm_asset_hub(
@@ -410,52 +452,106 @@ async fn run() -> Result<(), Box<dyn std::error::Error>> {
410452
let bridge_hub_call =
411453
send_xcm_bridge_hub(&context, vec![set_pricing_parameters]).await?;
412454
let asset_hub_call = send_xcm_asset_hub(&context, vec![set_ethereum_fee]).await?;
413-
utility_force_batch(vec![bridge_hub_call, asset_hub_call])
455+
utility_batch_all(vec![bridge_hub_call, asset_hub_call])
414456
}
415457
Command::HaltBridge(params) => {
416458
let mut bh_calls = vec![];
417459
let mut ah_calls = vec![];
418460
let mut halt_all = params.all;
419461
// if no individual option specified, assume halt the whole bridge.
420462
if !params.gateway
463+
&& !params.gateway_v2
421464
&& !params.inbound_queue
465+
&& !params.inbound_queue_v1
466+
&& !params.inbound_queue_v2
422467
&& !params.outbound_queue
468+
&& !params.system_frontend
423469
&& !params.ethereum_client
424470
&& !params.assethub_max_fee
471+
&& !params.assethub_max_fee_v2
425472
{
426473
halt_all = true;
427474
}
475+
// Gateway halt commands must be enqueued BEFORE any local outbound-queue
476+
// halt takes effect, otherwise the SetOperatingMode command cannot be
477+
// committed for delivery to Ethereum. Push both V1 and V2 variants so the
478+
// halt is delivered via whichever outbound queue is operational.
428479
if params.gateway || halt_all {
429480
bh_calls.push(commands::gateway_operating_mode(
430481
&GatewayOperatingModeEnum::RejectingOutboundMessages,
431482
));
483+
bh_calls.push(commands::gateway_operating_mode_v2(
484+
&GatewayOperatingModeEnum::RejectingOutboundMessages,
485+
));
486+
} else if params.gateway_v2 {
487+
// V2-only: leave V1 SetOperatingMode unsent.
488+
bh_calls.push(commands::gateway_operating_mode_v2(
489+
&GatewayOperatingModeEnum::RejectingOutboundMessages,
490+
));
432491
}
433-
if params.inbound_queue || halt_all {
492+
if params.inbound_queue || params.inbound_queue_v1 || halt_all {
434493
bh_calls.push(commands::inbound_queue_operating_mode(
435494
&OperatingModeEnum::Halted,
436495
));
437496
}
497+
if params.inbound_queue || params.inbound_queue_v2 || halt_all {
498+
bh_calls.push(commands::inbound_queue_v2_operating_mode(
499+
&OperatingModeEnum::Halted,
500+
));
501+
}
438502
if params.outbound_queue || halt_all {
503+
// V1 local halt on BridgeHub. V2's outbound-queue-v2 has no local halt;
504+
// the system-frontend halt below is the effective V2 outbound lever.
439505
bh_calls.push(commands::outbound_queue_operating_mode(
440506
&OperatingModeEnum::Halted,
441507
));
508+
// system-frontend halt on AssetHub: short-circuits the PausableExporter
509+
// wrapping the AH->Ethereum router, blocking both V1 and V2 exports at
510+
// the source regardless of user or parachain origin.
511+
ah_calls.push(commands::system_frontend_operating_mode(
512+
&OperatingModeEnum::Halted,
513+
));
514+
} else if params.system_frontend {
515+
// Router-layer halt: AH frontend, blocks both V1 and V2 P->E at the
516+
// PausableExporter. V1 BH outbound-queue left running so in-flight V1
517+
// messages continue to drain.
518+
ah_calls.push(commands::system_frontend_operating_mode(
519+
&OperatingModeEnum::Halted,
520+
));
442521
}
443522
if params.ethereum_client || halt_all {
444523
bh_calls.push(commands::ethereum_client_operating_mode(
445524
&OperatingModeEnum::Halted,
446525
));
447526
}
448527
if params.assethub_max_fee || halt_all {
528+
// Set both V1 and V2 AssetHub outbound fee storage items to u128::MAX.
449529
ah_calls.push(commands::set_assethub_fee(u128::MAX));
530+
ah_calls.push(commands::set_assethub_fee_v2(u128::MAX));
531+
} else if params.assethub_max_fee_v2 {
532+
// V2-only: leave V1 fee untouched.
533+
ah_calls.push(commands::set_assethub_fee_v2(u128::MAX));
450534
}
451-
if bh_calls.len() > 0 && ah_calls.len() == 0 {
535+
// Use `force_batch` (not `batch_all` or `batch`) so every lever fires
536+
// independently — a single failure (e.g. HRMP transport hiccup blocking
537+
// pallet_xcm::send to BridgeHub) must not skip the AH-side halts, and
538+
// vice versa. Per-call failures are reported via `ItemFailed` events.
539+
let ah_call = if ah_calls.len() == 1 {
540+
Some(ah_calls.into_iter().next().unwrap())
541+
} else if ah_calls.len() > 1 {
542+
Some(utility_force_batch(ah_calls))
543+
} else {
544+
None
545+
};
546+
if bh_calls.len() > 0 && ah_call.is_none() {
452547
send_xcm_bridge_hub(&context, bh_calls).await?
453-
} else if ah_calls.len() > 0 && bh_calls.len() == 0 {
454-
send_xcm_asset_hub(&context, ah_calls).await?
548+
} else if ah_call.is_some() && bh_calls.len() == 0 {
549+
ah_call.unwrap()
455550
} else {
456-
let call1 = send_xcm_bridge_hub(&context, bh_calls).await?;
457-
let call2 = send_xcm_asset_hub(&context, ah_calls).await?;
458-
utility_force_batch(vec![call1, call2])
551+
let bh_xcm_send = send_xcm_bridge_hub(&context, bh_calls).await?;
552+
// BH XCM-send is the first call so the V2 Gateway halt (the first
553+
// Transact inside the XCM) is processed before any AH-side halt.
554+
utility_force_batch(vec![bh_xcm_send, ah_call.unwrap()])
459555
}
460556
}
461557
Command::RegisterEther(params) => {
@@ -481,7 +577,7 @@ async fn run() -> Result<(), Box<dyn std::error::Error>> {
481577
send_xcm_asset_hub(&context, vec![register_ether_call, set_ether_metadata_call])
482578
.await?;
483579

484-
utility_force_batch(vec![
580+
utility_batch_all(vec![
485581
bh_set_pricing_call,
486582
ah_set_pricing_call,
487583
ah_register_ether_call,
@@ -506,7 +602,7 @@ async fn run() -> Result<(), Box<dyn std::error::Error>> {
506602
{
507603
let metadata_calls = commands::register_erc20_token_metadata();
508604
let reg_call = commands::frequency_token_registrations();
509-
utility_force_batch(vec![
605+
utility_batch_all(vec![
510606
send_xcm_asset_hub(&context, metadata_calls).await?,
511607
send_xcm_bridge_hub(&context, reg_call).await?,
512608
])
@@ -533,7 +629,7 @@ async fn run() -> Result<(), Box<dyn std::error::Error>> {
533629
let outbound_fee_call = commands::set_assethub_fee_v2(1_000_000_000);
534630
let ah_xcm_call = send_xcm_asset_hub(&context, vec![outbound_fee_call]).await?;
535631

536-
utility_force_batch(vec![bh_xcm_call, ah_xcm_call])
632+
utility_batch_all(vec![bh_xcm_call, ah_xcm_call])
537633
}
538634
}
539635
Command::ReplaySep2025 => {

control/preimage/src/treasury_commands.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::asset_hub_runtime::runtime_types::{
99
},
1010
};
1111
use crate::asset_hub_runtime::RuntimeCall as AssetHubRuntimeCall;
12-
use crate::helpers::utility_force_batch;
12+
use crate::helpers::utility_batch_all;
1313
use polkadot_runtime_constants::currency::UNITS;
1414
use polkadot_runtime_constants::time::DAYS;
1515

@@ -189,7 +189,7 @@ pub fn treasury_proposal(params: &TreasuryProposal2024Args) -> AssetHubRuntimeCa
189189
println!("Spend: {}, {}({})", spend.name, asset_id, asset_amount);
190190
}
191191

192-
utility_force_batch(calls)
192+
utility_batch_all(calls)
193193
}
194194

195195
fn make_treasury_spend(

docs/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
* [Processes for keeping track of dependency changes](resources/processes-for-keeping-track-of-dependency-changes.md)
4242
* [Contributing to Snowbridge](resources/updating-snowbridge-pallets-bridgehub-and-assethub-runtimes.md)
4343
* [Governance and Operational Processes](resources/governance-and-operational-processes.md)
44+
* [Emergency Procedures](resources/emergency-procedures.md)
4445
* [General Governance Updates](resources/governance-updates.md)
4546
* [Test Runtime Upgrades](resources/test-runtime-upgrades.md)
4647
* [Run Relayers](resources/run-relayers.md)

0 commit comments

Comments
 (0)