Skip to content

Commit

Permalink
[testnet] Allow governance to control fees for Rococo <> Westend brid…
Browse files Browse the repository at this point in the history
…ge (#2139)

Right now governance could only control byte-fee component of Rococo <>
Westend message fees (paid at Asset Hubs). This PR changes it a bit:
1) governance now allowed to control both fee components - byte fee and
base fee;
2) base fee now includes cost of "default" delivery and confirmation
transactions, in addition to `ExportMessage` instruction cost.
  • Loading branch information
svyatonik authored and bkontur committed Nov 6, 2023
1 parent aa0ea96 commit 644a1e3
Show file tree
Hide file tree
Showing 16 changed files with 801 additions and 131 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

54 changes: 15 additions & 39 deletions bridges/bin/runtime-common/src/messages_benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,22 @@
use crate::{
messages::{
source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof,
AccountIdOf, BridgedChain, HashOf, HasherOf, MessageBridge, ThisChain,
AccountIdOf, BridgedChain, HashOf, MessageBridge, ThisChain,
},
messages_generation::{
encode_all_messages, encode_lane_data, grow_trie_leaf_value, prepare_messages_storage_proof,
encode_all_messages, encode_lane_data, prepare_message_delivery_storage_proof,
prepare_messages_storage_proof,
},
};

use bp_messages::{storage_keys, MessagePayload};
use bp_messages::MessagePayload;
use bp_polkadot_core::parachains::ParaHash;
use bp_runtime::{
record_all_trie_keys, Chain, Parachain, RawStorageProof, StorageProofSize, UnderlyingChainOf,
};
use bp_runtime::{Chain, Parachain, StorageProofSize, UnderlyingChainOf};
use codec::Encode;
use frame_support::weights::Weight;
use pallet_bridge_messages::benchmarking::{MessageDeliveryProofParams, MessageProofParams};
use sp_runtime::traits::{Header, Zero};
use sp_std::prelude::*;
use sp_trie::{trie_types::TrieDBMutBuilderV1, LayoutV1, MemoryDB, TrieMut};
use xcm::v3::prelude::*;

/// Prepare inbound bridge message according to given message proof parameters.
Expand Down Expand Up @@ -172,7 +170,11 @@ where
{
// prepare storage proof
let lane = params.lane;
let (state_root, storage_proof) = prepare_message_delivery_proof::<B>(params);
let (state_root, storage_proof) = prepare_message_delivery_storage_proof::<B>(
params.lane,
params.inbound_lane_data,
params.size,
);

// update runtime storage
let (_, bridged_header_hash) = insert_header_to_grandpa_pallet::<R, FI>(state_root);
Expand Down Expand Up @@ -200,7 +202,11 @@ where
{
// prepare storage proof
let lane = params.lane;
let (state_root, storage_proof) = prepare_message_delivery_proof::<B>(params);
let (state_root, storage_proof) = prepare_message_delivery_storage_proof::<B>(
params.lane,
params.inbound_lane_data,
params.size,
);

// update runtime storage
let (_, bridged_header_hash) =
Expand All @@ -213,36 +219,6 @@ where
}
}

/// Prepare in-memory message delivery proof, without inserting anything to the runtime storage.
fn prepare_message_delivery_proof<B>(
params: MessageDeliveryProofParams<AccountIdOf<ThisChain<B>>>,
) -> (HashOf<BridgedChain<B>>, RawStorageProof)
where
B: MessageBridge,
{
// prepare Bridged chain storage with inbound lane state
let storage_key =
storage_keys::inbound_lane_data_key(B::BRIDGED_MESSAGES_PALLET_NAME, &params.lane).0;
let mut root = Default::default();
let mut mdb = MemoryDB::default();
{
let mut trie =
TrieDBMutBuilderV1::<HasherOf<BridgedChain<B>>>::new(&mut mdb, &mut root).build();
let inbound_lane_data =
grow_trie_leaf_value(params.inbound_lane_data.encode(), params.size);
trie.insert(&storage_key, &inbound_lane_data)
.map_err(|_| "TrieMut::insert has failed")
.expect("TrieMut::insert should not fail in benchmarks");
}

// generate storage proof to be delivered to This chain
let storage_proof = record_all_trie_keys::<LayoutV1<HasherOf<BridgedChain<B>>>, _>(&mdb, &root)
.map_err(|_| "record_all_trie_keys has failed")
.expect("record_all_trie_keys should not fail in benchmarks");

(root, storage_proof)
}

/// Insert header to the bridge GRANDPA pallet.
pub(crate) fn insert_header_to_grandpa_pallet<R, GI>(
state_root: bp_runtime::HashOf<R::BridgedChain>,
Expand Down
37 changes: 35 additions & 2 deletions bridges/bin/runtime-common/src/messages_generation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@

//! Helpers for generating message storage proofs, that are used by tests and by benchmarks.

use crate::messages::{BridgedChain, HashOf, HasherOf, MessageBridge};
use crate::messages::{AccountIdOf, BridgedChain, HashOf, HasherOf, MessageBridge, ThisChain};

use bp_messages::{
storage_keys, LaneId, MessageKey, MessageNonce, MessagePayload, OutboundLaneData,
storage_keys, InboundLaneData, LaneId, MessageKey, MessageNonce, MessagePayload,
OutboundLaneData,
};
use bp_runtime::{record_all_trie_keys, RawStorageProof, StorageProofSize};
use codec::Encode;
Expand Down Expand Up @@ -104,6 +105,38 @@ where
(root, storage_proof)
}

/// Prepare storage proof of given messages delivery.
///
/// Returns state trie root and nodes with prepared messages.
pub fn prepare_message_delivery_storage_proof<B>(
lane: LaneId,
inbound_lane_data: InboundLaneData<AccountIdOf<ThisChain<B>>>,
size: StorageProofSize,
) -> (HashOf<BridgedChain<B>>, RawStorageProof)
where
B: MessageBridge,
{
// prepare Bridged chain storage with inbound lane state
let storage_key = storage_keys::inbound_lane_data_key(B::BRIDGED_MESSAGES_PALLET_NAME, &lane).0;
let mut root = Default::default();
let mut mdb = MemoryDB::default();
{
let mut trie =
TrieDBMutBuilderV1::<HasherOf<BridgedChain<B>>>::new(&mut mdb, &mut root).build();
let inbound_lane_data = grow_trie_leaf_value(inbound_lane_data.encode(), size);
trie.insert(&storage_key, &inbound_lane_data)
.map_err(|_| "TrieMut::insert has failed")
.expect("TrieMut::insert should not fail in benchmarks");
}

// generate storage proof to be delivered to This chain
let storage_proof = record_all_trie_keys::<LayoutV1<HasherOf<BridgedChain<B>>>, _>(&mdb, &root)
.map_err(|_| "record_all_trie_keys has failed")
.expect("record_all_trie_keys should not fail in benchmarks");

(root, storage_proof)
}

/// Add extra data to the trie leaf value so that it'll be of given size.
pub fn grow_trie_leaf_value(mut value: Vec<u8>, size: StorageProofSize) -> Vec<u8> {
match size {
Expand Down
4 changes: 0 additions & 4 deletions bridges/primitives/chain-asset-hub-rococo/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,6 @@ pub enum Call {
frame_support::parameter_types! {
/// Some sane weight to execute `xcm::Transact(pallet-xcm-bridge-hub-router::Call::report_bridge_status)`.
pub const XcmBridgeHubRouterTransactCallMaxWeight: frame_support::weights::Weight = frame_support::weights::Weight::from_parts(200_000_000, 6144);

/// Base delivery fee to `BridgeHubRococo`.
/// (initially was calculated by test `BridgeHubRococo::can_calculate_weight_for_paid_export_message_with_reserve_transfer` + `33%`)
pub const BridgeHubRococoBaseFeeInRocs: u128 = 1624803349;
}

/// Identifier of AssetHubRococo in the Rococo relay chain.
Expand Down
4 changes: 0 additions & 4 deletions bridges/primitives/chain-asset-hub-westend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,6 @@ pub enum Call {
frame_support::parameter_types! {
/// Some sane weight to execute `xcm::Transact(pallet-xcm-bridge-hub-router::Call::report_bridge_status)`.
pub const XcmBridgeHubRouterTransactCallMaxWeight: frame_support::weights::Weight = frame_support::weights::Weight::from_parts(200_000_000, 6144);

/// Base delivery fee to `BridgeHubWestend`.
/// (initially was calculated by test `BridgeHubWestend::can_calculate_weight_for_paid_export_message_with_reserve_transfer` + `33%`)
pub const BridgeHubWestendBaseFeeInWnds: u128 = 487441010000;
}

/// Identifier of AssetHubWestend in the Westend relay chain.
Expand Down
4 changes: 0 additions & 4 deletions bridges/primitives/chain-asset-hub-wococo/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,6 @@ pub enum Call {
frame_support::parameter_types! {
/// Some sane weight to execute `xcm::Transact(pallet-xcm-bridge-hub-router::Call::report_bridge_status)`.
pub const XcmBridgeHubRouterTransactCallMaxWeight: frame_support::weights::Weight = frame_support::weights::Weight::from_parts(200_000_000, 6144);

/// Base delivery fee to `BridgeHubWococo`.
/// (initially was calculated by test `BridgeHubWococo::can_calculate_weight_for_paid_export_message_with_reserve_transfer` + `33%`)
pub const BridgeHubWococoBaseFeeInWocs: u128 = 1624803349;
}

/// Identifier of AssetHubWococo in the Wococo relay chain.
Expand Down
15 changes: 15 additions & 0 deletions bridges/primitives/chain-bridge-hub-rococo/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,18 @@ pub const WITH_BRIDGE_ROCOCO_TO_WESTEND_MESSAGES_PALLET_INDEX: u8 = 51;

decl_bridge_finality_runtime_apis!(bridge_hub_rococo);
decl_bridge_messages_runtime_apis!(bridge_hub_rococo);

frame_support::parameter_types! {
/// The XCM fee that is paid for executing XCM program (with `ExportMessage` instruction) at the Rococo
/// BridgeHub.
/// (initially was calculated by test `BridgeHubRococo::can_calculate_weight_for_paid_export_message_with_reserve_transfer` + `33%`)
pub const BridgeHubRococoBaseXcmFeeInRocs: u128 = 1628875538;

/// Transaction fee that is paid at the Rococo BridgeHub for delivering single inbound message.
/// (initially was calculated by test `BridgeHubRococo::can_calculate_fee_for_complex_message_delivery_transaction` + `33%`)
pub const BridgeHubRococoBaseDeliveryFeeInRocs: u128 = 6417262881;

/// Transaction fee that is paid at the Rococo BridgeHub for delivering single outbound message confirmation.
/// (initially was calculated by test `BridgeHubRococo::can_calculate_fee_for_complex_message_confirmation_transaction` + `33%`)
pub const BridgeHubRococoBaseConfirmationFeeInRocs: u128 = 6159996668;
}
15 changes: 15 additions & 0 deletions bridges/primitives/chain-bridge-hub-westend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,18 @@ pub const WITH_BRIDGE_WESTEND_TO_ROCOCO_MESSAGES_PALLET_INDEX: u8 = 44;

decl_bridge_finality_runtime_apis!(bridge_hub_westend);
decl_bridge_messages_runtime_apis!(bridge_hub_westend);

frame_support::parameter_types! {
/// The XCM fee that is paid for executing XCM program (with `ExportMessage` instruction) at the Westend
/// BridgeHub.
/// (initially was calculated by test `BridgeHubWestend::can_calculate_weight_for_paid_export_message_with_reserve_transfer` + `33%`)
pub const BridgeHubWestendBaseXcmFeeInWnds: u128 = 488662666666;

/// Transaction fee that is paid at the Westend BridgeHub for delivering single inbound message.
/// (initially was calculated by test `BridgeHubWestend::can_calculate_fee_for_complex_message_delivery_transaction` + `33%`)
pub const BridgeHubWestendBaseDeliveryFeeInWnds: u128 = 1925196628010;

/// Transaction fee that is paid at the Westend BridgeHub for delivering single outbound message confirmation.
/// (initially was calculated by test `BridgeHubWestend::can_calculate_fee_for_complex_message_confirmation_transaction` + `33%`)
pub const BridgeHubWestendBaseConfirmationFeeInWnds: u128 = 1848016628010;
}
15 changes: 15 additions & 0 deletions bridges/primitives/chain-bridge-hub-wococo/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,18 @@ pub const WITH_BRIDGE_WOCOCO_TO_ROCOCO_MESSAGES_PALLET_INDEX: u8 = 45;

decl_bridge_finality_runtime_apis!(bridge_hub_wococo);
decl_bridge_messages_runtime_apis!(bridge_hub_wococo);

frame_support::parameter_types! {
/// The XCM fee that is paid for executing XCM program (with `ExportMessage` instruction) at the Wococo
/// BridgeHub.
/// (initially was calculated by test `BridgeHubWococo::can_calculate_weight_for_paid_export_message_with_reserve_transfer` + `33%`)
pub const BridgeHubWococoBaseXcmFeeInWocs: u128 = 1624803349;

/// Transaction fee that is paid at the Wococo BridgeHub for delivering single inbound message.
/// (initially was calculated by test `BridgeHubWococo::can_calculate_fee_for_complex_message_delivery_transaction` + `33%`)
pub const BridgeHubWococoBaseDeliveryFeeInWocs: u128 = 6417262881;

/// Transaction fee that is paid at the Wococo BridgeHub for delivering single outbound message confirmation.
/// (initially was calculated by test `BridgeHubWococo::can_calculate_fee_for_complex_message_confirmation_transaction` + `33%`)
pub const BridgeHubWococoBaseConfirmationFeeInWocs: u128 = 6159996668;
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ bp-asset-hub-westend = { path = "../../../../../bridges/primitives/chain-asset-h
bp-asset-hub-wococo = { path = "../../../../../bridges/primitives/chain-asset-hub-wococo", default-features = false }
bp-bridge-hub-rococo = { path = "../../../../../bridges/primitives/chain-bridge-hub-rococo", default-features = false }
bp-bridge-hub-wococo = { path = "../../../../../bridges/primitives/chain-bridge-hub-wococo", default-features = false }
bp-bridge-hub-westend = { path = "../../../../../bridges/primitives/chain-bridge-hub-westend", default-features = false }

[dev-dependencies]
asset-test-utils = { path = "../test-utils" }
Expand Down Expand Up @@ -176,6 +177,7 @@ std = [
"bp-asset-hub-wococo/std",
"bp-bridge-hub-rococo/std",
"bp-bridge-hub-wococo/std",
"bp-bridge-hub-westend/std",
"codec/std",
"cumulus-pallet-aura-ext/std",
"cumulus-pallet-dmp-queue/std",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,9 @@ impl Contains<RuntimeCall> for SafeCallFilter {
match call {
RuntimeCall::System(frame_system::Call::set_storage { items })
if items.iter().all(|(k, _)| k.eq(&bridging::XcmBridgeHubRouterByteFee::key())) ||
items
.iter()
.all(|(k, _)| k.eq(&bridging::XcmBridgeHubRouterBaseFee::key())) ||
items.iter().all(|(k, _)| k.eq(&Flavor::key())) =>
return true,
_ => (),
Expand Down Expand Up @@ -760,6 +763,25 @@ pub mod bridging {

// common/shared parameters for Wococo/Rococo
parameter_types! {
/// Base price of every byte of the Rococo -> Westend message. Can be adjusted via
/// governance `set_storage` call.
///
/// Default value is our estimation of the:
///
/// 1) an approximate cost of XCM execution (`ExportMessage` and surroundings) at Rococo bridge hub;
///
/// 2) the approximate cost of Rococo -> Westend message delivery transaction on Westend Bridge Hub,
/// converted into ROCs using 1:1 conversion rate;
///
/// 3) the approximate cost of Rococo -> Westend message confirmation transaction on Rococo Bridge Hub.
pub storage XcmBridgeHubRouterBaseFee: Balance =
bp_bridge_hub_rococo::BridgeHubRococoBaseXcmFeeInRocs::get()
.saturating_add(bp_bridge_hub_westend::BridgeHubWestendBaseDeliveryFeeInWnds::get())
.saturating_add(bp_bridge_hub_rococo::BridgeHubRococoBaseConfirmationFeeInRocs::get());
/// Price of every byte of the Rococo -> Westend message. Can be adjusted via
/// governance `set_storage` call.
pub storage XcmBridgeHubRouterByteFee: Balance = TransactionByteFee::get();

pub SiblingBridgeHubParaId: u32 = match Flavor::get() {
RuntimeFlavor::Rococo => bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID,
RuntimeFlavor::Wococo => bp_bridge_hub_wococo::BRIDGE_HUB_WOCOCO_PARACHAIN_ID,
Expand All @@ -768,8 +790,6 @@ pub mod bridging {
/// Router expects payment with this `AssetId`.
/// (`AssetId` has to be aligned with `BridgeTable`)
pub XcmBridgeHubRouterFeeAssetId: AssetId = TokenLocation::get().into();
/// Price per byte - can be adjusted via governance `set_storage` call.
pub storage XcmBridgeHubRouterByteFee: Balance = TransactionByteFee::get();

pub BridgeTable: sp_std::vec::Vec<NetworkExportTableItem> =
sp_std::vec::Vec::new().into_iter()
Expand Down Expand Up @@ -814,7 +834,7 @@ pub mod bridging {
// base delivery fee to local `BridgeHub`
Some((
XcmBridgeHubRouterFeeAssetId::get(),
bp_asset_hub_rococo::BridgeHubRococoBaseFeeInRocs::get(),
XcmBridgeHubRouterBaseFee::get(),
).into())
)
];
Expand Down Expand Up @@ -890,7 +910,7 @@ pub mod bridging {
// base delivery fee to local `BridgeHub`
Some((
XcmBridgeHubRouterFeeAssetId::get(),
bp_asset_hub_rococo::BridgeHubRococoBaseFeeInRocs::get(),
XcmBridgeHubRouterBaseFee::get(),
).into())
)
];
Expand Down Expand Up @@ -966,7 +986,7 @@ pub mod bridging {
// base delivery fee to local `BridgeHub`
Some((
XcmBridgeHubRouterFeeAssetId::get(),
bp_asset_hub_wococo::BridgeHubWococoBaseFeeInWocs::get(),
XcmBridgeHubRouterBaseFee::get(),
).into())
)
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ assets-common = { path = "../common", default-features = false }
pallet-xcm-bridge-hub-router = { path = "../../../../../bridges/modules/xcm-bridge-hub-router", default-features = false }
bp-asset-hub-rococo = { path = "../../../../../bridges/primitives/chain-asset-hub-rococo", default-features = false }
bp-asset-hub-westend = { path = "../../../../../bridges/primitives/chain-asset-hub-westend", default-features = false }
bp-bridge-hub-rococo = { path = "../../../../../bridges/primitives/chain-bridge-hub-rococo", default-features = false }
bp-bridge-hub-westend = { path = "../../../../../bridges/primitives/chain-bridge-hub-westend", default-features = false }

[dev-dependencies]
Expand Down Expand Up @@ -162,6 +163,7 @@ std = [
"assets-common/std",
"bp-asset-hub-rococo/std",
"bp-asset-hub-westend/std",
"bp-bridge-hub-rococo/std",
"bp-bridge-hub-westend/std",
"codec/std",
"cumulus-pallet-aura-ext/std",
Expand Down
Loading

0 comments on commit 644a1e3

Please sign in to comment.