diff --git a/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs b/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs index 213087f5bd2c..cc11533c86bb 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs @@ -18,10 +18,10 @@ #![cfg(feature = "runtime-benchmarks")] -use crate::{BridgeState, ResolveBridgeId, Bridges, Call, MINIMAL_DELIVERY_FEE_FACTOR}; +use crate::{BridgeState, Bridges, Call, ResolveBridgeId, MINIMAL_DELIVERY_FEE_FACTOR}; use frame_benchmarking::{benchmarks_instance_pallet, BenchmarkError, BenchmarkResult}; -use frame_support::traits::{UnfilteredDispatchable, EnsureOriginWithArg, Hooks}; -use sp_runtime::{Saturating, traits::Zero}; +use frame_support::traits::{EnsureOriginWithArg, Hooks, UnfilteredDispatchable}; +use sp_runtime::{traits::Zero, Saturating}; use xcm::prelude::*; /// Pallet we're benchmarking here. diff --git a/bridges/modules/xcm-bridge-hub-router/src/impls.rs b/bridges/modules/xcm-bridge-hub-router/src/impls.rs index 789f445d8aa4..c6431e1215d6 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/impls.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/impls.rs @@ -68,8 +68,11 @@ impl, I: 'static> bp_xcm_bridge_hub::LocalXcmChannelManager(PhantomData<(T, I, E, BNF, BHLF)>); impl, I: 'static, E, BridgedNetworkIdFilter, BridgeHubLocationFilter> ExporterFor for ViaRemoteBridgeHubExporter @@ -188,32 +191,40 @@ where } } -/// Adapter implementation for `SendXcm` that allows adding a message size fee and/or dynamic fees based on the `BridgeId` resolved by the `T::BridgeIdResolver` resolver, -/// if and only if `E` supports routing. -/// This adapter can be used, for example, as a wrapper over `UnpaidLocalExporter`, enabling it to compute message and/or dynamic fees using a fee factor. +/// Adapter implementation for `SendXcm` that allows adding a message size fee and/or dynamic fees +/// based on the `BridgeId` resolved by the `T::BridgeIdResolver` resolver, if and only if `E` +/// supports routing. This adapter can be used, for example, as a wrapper over +/// `UnpaidLocalExporter`, enabling it to compute message and/or dynamic fees using a fee factor. pub struct ViaLocalBridgeHubExporter(PhantomData<(T, I, E)>); impl, I: 'static, E: SendXcm> SendXcm for ViaLocalBridgeHubExporter { type Ticket = E::Ticket; - fn validate(destination: &mut Option, message: &mut Option>) -> SendResult { + fn validate( + destination: &mut Option, + message: &mut Option>, + ) -> SendResult { let dest_clone = destination.clone().ok_or(SendError::MissingArgument)?; - let message_size = message.as_ref().map_or(0, |message|message.encoded_size()) as _; + let message_size = message.as_ref().map_or(0, |message| message.encoded_size()) as _; match E::validate(destination, message) { Ok((ticket, mut fees)) => { // calculate message size fees (if configured) - let maybe_message_size_fees = Pallet::::calculate_message_size_fees(|| message_size); + let maybe_message_size_fees = + Pallet::::calculate_message_size_fees(|| message_size); if let Some(message_size_fees) = maybe_message_size_fees { fees.push(message_size_fees); } - // Here, we have the actual result fees covering bridge fees, so now we need to check/apply - // the congestion and dynamic_fees features (if possible). + // Here, we have the actual result fees covering bridge fees, so now we need to + // check/apply the congestion and dynamic_fees features (if possible). if let Some(bridge_id) = T::BridgeIdResolver::resolve_for_dest(&dest_clone) { if let Some(bridge_state) = Bridges::::get(bridge_id) { let mut dynamic_fees = sp_std::vec::Vec::with_capacity(fees.len()); for fee in fees.into_inner() { - dynamic_fees.push(Pallet::::calculate_dynamic_fees_for_asset(&bridge_state, fee)); + dynamic_fees.push(Pallet::::calculate_dynamic_fees_for_asset( + &bridge_state, + fee, + )); } fees = Assets::from(dynamic_fees); } @@ -221,8 +232,8 @@ impl, I: 'static, E: SendXcm> SendXcm for ViaLocalBridgeHubExporter // return original ticket with possibly extended fees Ok((ticket, fees)) - } - e => e + }, + e => e, } } @@ -231,7 +242,6 @@ impl, I: 'static, E: SendXcm> SendXcm for ViaLocalBridgeHubExporter } } - /// Implementation of `ResolveBridgeId` returning `bp_xcm_bridge_hub::BridgeId` based on the /// configured `UniversalLocation` and remote universal location. pub struct EnsureIsRemoteBridgeIdResolver(PhantomData); diff --git a/bridges/modules/xcm-bridge-hub-router/src/lib.rs b/bridges/modules/xcm-bridge-hub-router/src/lib.rs index 15806142f7c3..1a371de05983 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/lib.rs @@ -14,36 +14,51 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -//! A pallet that can be used as an alternative in the XCM router configuration — see the `SendXcm` implementation for details. +//! A pallet that can be used as an alternative in the XCM router configuration — see the `SendXcm` +//! implementation for details. //! //! ## Features //! //! This pallet offers several optional features to customize functionality: //! //! ### Message Size Fee -//! An optional fee based on `T::FeeAsset` and `T::ByteFee`. If `T::FeeAsset` is not specified, this fee is not calculated. +//! An optional fee based on `T::FeeAsset` and `T::ByteFee`. If `T::FeeAsset` is not specified, this +//! fee is not calculated. //! //! ### Dynamic Fees and Congestion //! -//! This pallet supports storing the congestion status of bridge outbound queues. The fee increases exponentially if the queue between this chain and a sibling or child bridge hub becomes congested. All other bridge hub queues provide backpressure mechanisms, so if any of these queues are congested, it will eventually lead to increased queuing on this chain. +//! This pallet supports storing the congestion status of bridge outbound queues. The fee increases +//! exponentially if the queue between this chain and a sibling or child bridge hub becomes +//! congested. All other bridge hub queues provide backpressure mechanisms, so if any of these +//! queues are congested, it will eventually lead to increased queuing on this chain. //! //! There are two methods for storing congestion status: -//! 1. A dedicated extrinsic `report_bridge_status`, which relies on `T::BridgeHubOrigin`. This allows the message exporter to send, for example, an XCM `Transact`. +//! 1. A dedicated extrinsic `report_bridge_status`, which relies on `T::BridgeHubOrigin`. This +//! allows the message exporter to send, for example, an XCM `Transact`. //! 2. An implementation of `bp_xcm_bridge_hub::LocalXcmChannelManager`. //! //! ## Usage //! -//! This pallet provides several implementations, such as `ViaLocalBridgeHubExporter` and `ViaRemoteBridgeHubExporter`, which can expose or access these features. +//! This pallet provides several implementations, such as `ViaLocalBridgeHubExporter` and +//! `ViaRemoteBridgeHubExporter`, which can expose or access these features. //! -//! This router can be used in two main scenarios, depending on where the router and message exporter (e.g., `pallet_xcm_bridge_hub` or another pallet with an `ExportXcm` implementation) are deployed: +//! This router can be used in two main scenarios, depending on where the router and message +//! exporter (e.g., `pallet_xcm_bridge_hub` or another pallet with an `ExportXcm` implementation) +//! are deployed: //! //! ### On the Same Chain as the Message Exporter -//! In this setup, the router directly calls an `ExportXcm` implementation. In this case, `ViaLocalBridgeHubExporter` can be used as a wrapper with `T::ToBridgeHubSender`. +//! In this setup, the router directly calls an `ExportXcm` implementation. In this case, +//! `ViaLocalBridgeHubExporter` can be used as a wrapper with `T::ToBridgeHubSender`. //! //! ### On a Different Chain than the Message Exporter -//! In this setup, we need to provide a `SendXcm` implementation for `T::ToBridgeHubSender`, which sends `ExportMessage`. For example, `SovereignPaidRemoteExporter` can be used with `ViaRemoteBridgeHubExporter`. +//! In this setup, we need to provide a `SendXcm` implementation for `T::ToBridgeHubSender`, which +//! sends `ExportMessage`. For example, `SovereignPaidRemoteExporter` can be used with +//! `ViaRemoteBridgeHubExporter`. //! -//! **Note on Terminology**: When we refer to the bridge hub, we mean the chain that has the `pallet-bridge-messages` with an `ExportXcm` implementation deployed, such as `pallet-xcm-bridge-hub`. Depending on the deployment setup, `T::ToBridgeHubSender` can be configured accordingly—see `T::ToBridgeHubSender` for additional documentation. +//! **Note on Terminology**: When we refer to the bridge hub, we mean the chain that has the +//! `pallet-bridge-messages` with an `ExportXcm` implementation deployed, such as +//! `pallet-xcm-bridge-hub`. Depending on the deployment setup, `T::ToBridgeHubSender` can be +//! configured accordingly—see `T::ToBridgeHubSender` for additional documentation. #![cfg_attr(not(feature = "std"), no_std)] @@ -829,7 +844,6 @@ mod tests { Pallet::::update_bridge_status(bridge_id, false); assert!(get_bridge_state_for::(&dest).is_none()); - // update as is_congested=true Pallet::::update_bridge_status(bridge_id, true); assert_eq!( diff --git a/bridges/modules/xcm-bridge-hub-router/src/mock.rs b/bridges/modules/xcm-bridge-hub-router/src/mock.rs index 6f65e3f30a0c..e7c53579775d 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/mock.rs @@ -225,4 +225,4 @@ impl crate::benchmarking::Config<()> for TestRuntime { fn ensure_bridged_target_destination() -> Result { Ok(Location::new(2, [GlobalConsensus(BridgedNetworkId::get())])) } -} \ No newline at end of file +} diff --git a/bridges/modules/xcm-bridge-hub/src/lib.rs b/bridges/modules/xcm-bridge-hub/src/lib.rs index 59d273bb0b0c..7af7dbb96a21 100644 --- a/bridges/modules/xcm-bridge-hub/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub/src/lib.rs @@ -296,8 +296,9 @@ pub mod pallet { /// The states after this call: bridge is `Opened`, outbound lane is `Opened`, inbound lane /// is `Opened`. /// - /// Optional `maybe_notify` holds data about the `bridge_origin_relative_location` where notifications can be sent to - /// handle congestion. The notification contains an encoded tuple `(BridgeId, bool)`, where `bool` is the `is_congested` flag. + /// Optional `maybe_notify` holds data about the `bridge_origin_relative_location` where + /// notifications can be sent to handle congestion. The notification contains an encoded + /// tuple `(BridgeId, bool)`, where `bool` is the `is_congested` flag. #[pallet::call_index(0)] #[pallet::weight(Weight::zero())] // TODO:(bridges-v2) - https://github.com/paritytech/parity-bridges-common/issues/3046 - add benchmarks impl FAIL-CI pub fn open_bridge( @@ -472,13 +473,14 @@ pub mod pallet { bridge_destination_universal_location: Box, maybe_notify: Option, ) -> DispatchResult { - let locations = Self::bridge_locations_from_origin(origin, bridge_destination_universal_location)?; + let locations = + Self::bridge_locations_from_origin(origin, bridge_destination_universal_location)?; Bridges::::try_mutate_exists(locations.bridge_id(), |bridge| match bridge { Some(b) => { b.maybe_notify = maybe_notify; Self::deposit_event(Event::::NotificationReceiverUpdated { - bridge_id: * locations.bridge_id(), + bridge_id: *locations.bridge_id(), maybe_notify: b.maybe_notify.clone(), }); Ok(()) @@ -856,7 +858,7 @@ pub mod pallet { bridge_id: BridgeId, /// Updated notification receiver. maybe_notify: Option, - } + }, } #[pallet::error] @@ -1225,7 +1227,7 @@ mod tests { state: BridgeState::Opened, deposit: expected_deposit.clone(), lane_id, - maybe_notify: maybe_notify, + maybe_notify, }), ); assert_eq!( @@ -1514,51 +1516,58 @@ mod tests { let origin = OpenBridgeOrigin::parent_relay_chain_origin(); let locations = XcmOverBridge::bridge_locations_from_origin( origin.clone(), - Box::new( - VersionedInteriorLocation::from(bridged_asset_hub_universal_location()) - ), - ).unwrap(); + Box::new(VersionedInteriorLocation::from(bridged_asset_hub_universal_location())), + ) + .unwrap(); // open the bridge assert_ok!(XcmOverBridge::open_bridge( - origin.clone(), - Box::new(locations.bridge_destination_universal_location().clone().into()), - Some(Receiver::new(13, 15)), - )); + origin.clone(), + Box::new(locations.bridge_destination_universal_location().clone().into()), + Some(Receiver::new(13, 15)), + )); assert_eq!( - Bridges::::get(locations.bridge_id()).map(|b| b.maybe_notify).unwrap(), + Bridges::::get(locations.bridge_id()) + .map(|b| b.maybe_notify) + .unwrap(), Some(Receiver::new(13, 15)) ); // update the notification receiver to `None` assert_ok!(XcmOverBridge::update_notification_receiver( - origin.clone(), - Box::new(locations.bridge_destination_universal_location().clone().into()), - None, - )); + origin.clone(), + Box::new(locations.bridge_destination_universal_location().clone().into()), + None, + )); assert_eq!( - Bridges::::get(locations.bridge_id()).map(|b| b.maybe_notify).unwrap(), + Bridges::::get(locations.bridge_id()) + .map(|b| b.maybe_notify) + .unwrap(), None, ); // update the notification receiver to `Some(..)` assert_ok!(XcmOverBridge::update_notification_receiver( - origin.clone(), - Box::new(locations.bridge_destination_universal_location().clone().into()), - Some(Receiver::new(29, 43)), - )); + origin.clone(), + Box::new(locations.bridge_destination_universal_location().clone().into()), + Some(Receiver::new(29, 43)), + )); assert_eq!( - Bridges::::get(locations.bridge_id()).map(|b| b.maybe_notify).unwrap(), + Bridges::::get(locations.bridge_id()) + .map(|b| b.maybe_notify) + .unwrap(), Some(Receiver::new(29, 43)) ); // update the notification receiver to `Some(..)` assert_ok!(XcmOverBridge::update_notification_receiver( - origin.clone(), - Box::new(locations.bridge_destination_universal_location().clone().into()), - Some(Receiver::new(29, 79)), - )); + origin.clone(), + Box::new(locations.bridge_destination_universal_location().clone().into()), + Some(Receiver::new(29, 79)), + )); assert_eq!( - Bridges::::get(locations.bridge_id()).map(|b| b.maybe_notify).unwrap(), + Bridges::::get(locations.bridge_id()) + .map(|b| b.maybe_notify) + .unwrap(), Some(Receiver::new(29, 79)) ); }); diff --git a/bridges/modules/xcm-bridge-hub/src/migration.rs b/bridges/modules/xcm-bridge-hub/src/migration.rs index f69502a65470..32761a1cfa5a 100644 --- a/bridges/modules/xcm-bridge-hub/src/migration.rs +++ b/bridges/modules/xcm-bridge-hub/src/migration.rs @@ -16,7 +16,7 @@ //! A module that is responsible for migration of storage. -use crate::{Config, Pallet, LOG_TARGET, Receiver}; +use crate::{Config, Pallet, Receiver, LOG_TARGET}; use frame_support::{ traits::{Get, OnRuntimeUpgrade, StorageVersion}, weights::Weight, @@ -59,7 +59,15 @@ impl< BridgedUniversalLocation: Get, MaybeNotifyRelativeLocation: Get>, > OnRuntimeUpgrade - for OpenBridgeForLane + for OpenBridgeForLane< + T, + I, + Lane, + CreateLane, + SourceRelativeLocation, + BridgedUniversalLocation, + MaybeNotifyRelativeLocation, + > { fn on_runtime_upgrade() -> Weight { let bridge_origin_relative_location = SourceRelativeLocation::get(); @@ -108,7 +116,9 @@ impl< return T::DbWeight::get().reads(2) } - if let Err(e) = Pallet::::do_open_bridge(locations, lane_id, create_lane, maybe_notify) { + if let Err(e) = + Pallet::::do_open_bridge(locations, lane_id, create_lane, maybe_notify) + { log::error!(target: LOG_TARGET, "OpenBridgeForLane - do_open_bridge failed with error: {e:?}"); T::DbWeight::get().reads(6) } else { diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index 6af1d28c78b2..8573436a3dcd 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -272,12 +272,12 @@ impl pallet_xcm_bridge_hub_router::Config<()> for TestRuntime { pub type XcmOverBridgeByExportXcmRouterInstance = pallet_xcm_bridge_hub_router::Instance2; #[derive_impl(pallet_xcm_bridge_hub_router::config_preludes::TestDefaultConfig)] impl pallet_xcm_bridge_hub_router::Config for TestRuntime { - // We use `UnpaidLocalExporter` with `ViaLocalBridgeHubExporter` here to test and ensure that `pallet_xcm_bridge_hub_router` can - // trigger directly `pallet_xcm_bridge_hub` as exporter. + // We use `UnpaidLocalExporter` with `ViaLocalBridgeHubExporter` here to test and ensure that + // `pallet_xcm_bridge_hub_router` can trigger directly `pallet_xcm_bridge_hub` as exporter. type ToBridgeHubSender = pallet_xcm_bridge_hub_router::impls::ViaLocalBridgeHubExporter< TestRuntime, XcmOverBridgeByExportXcmRouterInstance, - UnpaidLocalExporter + UnpaidLocalExporter, >; type BridgeIdResolver = @@ -550,10 +550,7 @@ impl Convert, Xcm<()>> for ReportBridgeStatusXcmProvider { fn convert(encoded_call: Vec) -> Xcm<()> { Xcm(vec![ UnpaidExecution { weight_limit: Unlimited, check_origin: None }, - Transact { - origin_kind: OriginKind::Xcm, - call: encoded_call.into(), - }, + Transact { origin_kind: OriginKind::Xcm, call: encoded_call.into() }, ExpectTransactStatus(MaybeErrorCode::Success), ]) } diff --git a/bridges/primitives/xcm-bridge-hub/src/call_info.rs b/bridges/primitives/xcm-bridge-hub/src/call_info.rs index 5fa93711b341..28323dbeed07 100644 --- a/bridges/primitives/xcm-bridge-hub/src/call_info.rs +++ b/bridges/primitives/xcm-bridge-hub/src/call_info.rs @@ -32,7 +32,8 @@ pub enum XcmBridgeHubCall { open_bridge { /// Universal `InteriorLocation` from the bridged consensus. bridge_destination_universal_location: Box, - /// Optional `maybe_notify` holds data about the `bridge_origin_relative_location` where notifications can be sent to handle congestion. + /// Optional `maybe_notify` holds data about the `bridge_origin_relative_location` where + /// notifications can be sent to handle congestion. maybe_notify: Option, }, /// `pallet_xcm_bridge_hub::Call::close_bridge` diff --git a/bridges/primitives/xcm-bridge-hub/src/lib.rs b/bridges/primitives/xcm-bridge-hub/src/lib.rs index 2a353b7fda13..719e7439cfa7 100644 --- a/bridges/primitives/xcm-bridge-hub/src/lib.rs +++ b/bridges/primitives/xcm-bridge-hub/src/lib.rs @@ -187,7 +187,16 @@ pub struct Bridge { /// Receiver metadata. #[derive( - CloneNoBound, Decode, Encode, Eq, PartialEqNoBound, TypeInfo, MaxEncodedLen, RuntimeDebugNoBound, Serialize, Deserialize, + CloneNoBound, + Decode, + Encode, + Eq, + PartialEqNoBound, + TypeInfo, + MaxEncodedLen, + RuntimeDebugNoBound, + Serialize, + Deserialize, )] pub struct Receiver { /// Pallet index. diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs index 1f0d2f1be715..2abfedfa8c4c 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs @@ -135,10 +135,7 @@ impl Convert, Xcm<()>> for ReportBridgeStatusXcmProvider { fn convert(encoded_call: Vec) -> Xcm<()> { Xcm(vec![ UnpaidExecution { weight_limit: Unlimited, check_origin: None }, - Transact { - origin_kind: OriginKind::Xcm, - call: encoded_call.into(), - }, + Transact { origin_kind: OriginKind::Xcm, call: encoded_call.into() }, ExpectTransactStatus(MaybeErrorCode::Success), ]) } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs index 1652236b46ea..0bd7b246a0e2 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs @@ -32,7 +32,12 @@ fn bridge_hub_rococo_genesis( id: ParaId, bridges_pallet_owner: Option, asset_hub_para_id: ParaId, - opened_bridges: Vec<(Location, InteriorLocation, Option, Option)>, + opened_bridges: Vec<( + Location, + InteriorLocation, + Option, + Option, + )>, ) -> serde_json::Value { let config = RuntimeGenesisConfig { balances: BalancesConfig { diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs index 48ce74d13b99..34fada7258f5 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs @@ -166,10 +166,7 @@ impl Convert, Xcm<()>> for ReportBridgeStatusXcmProvider { fn convert(encoded_call: Vec) -> Xcm<()> { Xcm(vec![ UnpaidExecution { weight_limit: Unlimited, check_origin: None }, - Transact { - origin_kind: OriginKind::Xcm, - call: encoded_call.into(), - }, + Transact { origin_kind: OriginKind::Xcm, call: encoded_call.into() }, ExpectTransactStatus(MaybeErrorCode::Success), ]) } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/genesis_config_presets.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/genesis_config_presets.rs index c0f80a7976f1..bd3245538359 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/genesis_config_presets.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/genesis_config_presets.rs @@ -32,7 +32,12 @@ fn bridge_hub_westend_genesis( id: ParaId, bridges_pallet_owner: Option, asset_hub_para_id: ParaId, - opened_bridges: Vec<(Location, InteriorLocation, Option, Option)>, + opened_bridges: Vec<( + Location, + InteriorLocation, + Option, + Option, + )>, ) -> serde_json::Value { let config = RuntimeGenesisConfig { balances: BalancesConfig {