Commits on Source (46)
...@@ -5,28 +5,41 @@ on: ...@@ -5,28 +5,41 @@ on:
- Review-Trigger - Review-Trigger
types: types:
- completed - completed
workflow_dispatch:
inputs:
pr-number:
description: "Number of the PR to evaluate"
required: true
type: number
jobs: jobs:
review-approvals: review-approvals:
runs-on: ubuntu-latest runs-on: ubuntu-latest
environment: master environment: master
steps: steps:
- name: Generate token
id: app_token
uses: actions/[email protected]
with:
app-id: ${{ secrets.REVIEW_APP_ID }}
private-key: ${{ secrets.REVIEW_APP_KEY }}
- name: Extract content of artifact - name: Extract content of artifact
if: ${{ !inputs.pr-number }}
id: number id: number
uses: Bullrich/[email protected].0 uses: Bullrich/[email protected].1
with: with:
artifact-name: pr_number artifact-name: pr_number
- name: Generate token
id: app_token
uses: tibdex/github-app-token@v1
with:
app_id: ${{ secrets.REVIEW_APP_ID }}
private_key: ${{ secrets.REVIEW_APP_KEY }}
- name: "Evaluates PR reviews and assigns reviewers" - name: "Evaluates PR reviews and assigns reviewers"
uses: paritytech/[email protected] uses: paritytech/[email protected]
with: with:
repo-token: ${{ steps.app_token.outputs.token }} repo-token: ${{ steps.app_token.outputs.token }}
team-token: ${{ steps.app_token.outputs.token }} team-token: ${{ steps.app_token.outputs.token }}
checks-token: ${{ steps.app_token.outputs.token }} checks-token: ${{ steps.app_token.outputs.token }}
pr-number: ${{ steps.number.outputs.content }} # This is extracted from the triggering event
pr-number: ${{ inputs.pr-number || steps.number.outputs.content }}
request-reviewers: true request-reviewers: true
- name: Log payload
if: ${{ failure() || runner.debug }}
run: echo "::debug::$payload"
env:
payload: ${{ toJson(github.event) }}
...@@ -65,7 +65,7 @@ jobs: ...@@ -65,7 +65,7 @@ jobs:
echo "Saving PR number: $PR_NUMBER" echo "Saving PR number: $PR_NUMBER"
mkdir -p ./pr mkdir -p ./pr
echo $PR_NUMBER > ./pr/pr_number echo $PR_NUMBER > ./pr/pr_number
- uses: actions/upload-artifact@v3 - uses: actions/upload-artifact@v4
name: Save PR number name: Save PR number
with: with:
name: pr_number name: pr_number
......
...@@ -61,7 +61,7 @@ jobs: ...@@ -61,7 +61,7 @@ jobs:
- name: Install toml-cli - name: Install toml-cli
run: cargo install --git https://github.com/gnprice/toml-cli --rev ea69e9d2ca4f0f858110dc7a5ae28bcb918c07fb # v0.2.3 run: cargo install --git https://github.com/gnprice/toml-cli --rev ea69e9d2ca4f0f858110dc7a5ae28bcb918c07fb # v0.2.3
- name: Install Polkadot SDK Version Manager - name: Install Polkadot SDK Version Manager
run: cargo install --git https://github.com/paritytech/psvm --rev c41261ffb52ab0c115adbbdb17e2cb7900d2bdfd psvm # master run: cargo install --git https://github.com/paritytech/psvm psvm
- name: Rust compilation prerequisites - name: Rust compilation prerequisites
run: | run: |
sudo apt update sudo apt update
......
...@@ -132,7 +132,6 @@ check-runtime-migration-westend: ...@@ -132,7 +132,6 @@ check-runtime-migration-westend:
WASM: "westend_runtime.compact.compressed.wasm" WASM: "westend_runtime.compact.compressed.wasm"
URI: "wss://westend-try-runtime-node.parity-chains.parity.io:443" URI: "wss://westend-try-runtime-node.parity-chains.parity.io:443"
SUBCOMMAND_EXTRA_ARGS: "--no-weight-warnings" SUBCOMMAND_EXTRA_ARGS: "--no-weight-warnings"
allow_failure: true
check-runtime-migration-rococo: check-runtime-migration-rococo:
stage: check stage: check
......
...@@ -74,6 +74,8 @@ publish-subsystem-benchmarks: ...@@ -74,6 +74,8 @@ publish-subsystem-benchmarks:
artifacts: true artifacts: true
- job: subsystem-benchmark-availability-distribution - job: subsystem-benchmark-availability-distribution
artifacts: true artifacts: true
- job: subsystem-benchmark-approval-voting
artifacts: true
- job: publish-rustdoc - job: publish-rustdoc
artifacts: false artifacts: false
script: script:
...@@ -115,6 +117,8 @@ trigger_workflow: ...@@ -115,6 +117,8 @@ trigger_workflow:
artifacts: true artifacts: true
- job: subsystem-benchmark-availability-distribution - job: subsystem-benchmark-availability-distribution
artifacts: true artifacts: true
- job: subsystem-benchmark-approval-voting
artifacts: true
script: script:
- echo "Triggering workflow" - echo "Triggering workflow"
- > - >
......
...@@ -511,7 +511,7 @@ test-syscalls: ...@@ -511,7 +511,7 @@ test-syscalls:
fi fi
allow_failure: false # this rarely triggers in practice allow_failure: false # this rarely triggers in practice
subsystem-benchmark-availability-recovery: .subsystem-benchmark-template:
stage: test stage: test
artifacts: artifacts:
name: "${CI_JOB_NAME}_${CI_COMMIT_REF_NAME}" name: "${CI_JOB_NAME}_${CI_COMMIT_REF_NAME}"
...@@ -523,26 +523,26 @@ subsystem-benchmark-availability-recovery: ...@@ -523,26 +523,26 @@ subsystem-benchmark-availability-recovery:
- .docker-env - .docker-env
- .common-refs - .common-refs
- .run-immediately - .run-immediately
script:
- cargo bench -p polkadot-availability-recovery --bench availability-recovery-regression-bench --features subsystem-benchmarks
tags: tags:
- benchmark - benchmark
subsystem-benchmark-availability-recovery:
extends:
- .subsystem-benchmark-template
script:
- cargo bench -p polkadot-availability-recovery --bench availability-recovery-regression-bench --features subsystem-benchmarks
allow_failure: true allow_failure: true
subsystem-benchmark-availability-distribution: subsystem-benchmark-availability-distribution:
stage: test
artifacts:
name: "${CI_JOB_NAME}_${CI_COMMIT_REF_NAME}"
when: always
expire_in: 1 hour
paths:
- charts/
extends: extends:
- .docker-env - .subsystem-benchmark-template
- .common-refs
- .run-immediately
script: script:
- cargo bench -p polkadot-availability-distribution --bench availability-distribution-regression-bench --features subsystem-benchmarks - cargo bench -p polkadot-availability-distribution --bench availability-distribution-regression-bench --features subsystem-benchmarks
tags: allow_failure: true
- benchmark
subsystem-benchmark-approval-voting:
extends:
- .subsystem-benchmark-template
script:
- cargo bench -p polkadot-node-core-approval-voting --bench approval-voting-regression-bench --features subsystem-benchmarks
allow_failure: true allow_failure: true
...@@ -55,9 +55,9 @@ zombienet-bridges-0001-asset-transfer-works: ...@@ -55,9 +55,9 @@ zombienet-bridges-0001-asset-transfer-works:
- /home/nonroot/bridges-polkadot-sdk/bridges/testing/run-new-test.sh 0001-asset-transfer --docker - /home/nonroot/bridges-polkadot-sdk/bridges/testing/run-new-test.sh 0001-asset-transfer --docker
- echo "Done" - echo "Done"
zombienet-bridges-0002-mandatory-headers-synced-while-idle: zombienet-bridges-0002-free-headers-synced-while-idle:
extends: extends:
- .zombienet-bridges-common - .zombienet-bridges-common
script: script:
- /home/nonroot/bridges-polkadot-sdk/bridges/testing/run-new-test.sh 0002-mandatory-headers-synced-while-idle --docker - /home/nonroot/bridges-polkadot-sdk/bridges/testing/run-new-test.sh 0002-free-headers-synced-while-idle --docker
- echo "Done" - echo "Done"
...@@ -2153,6 +2153,7 @@ dependencies = [ ...@@ -2153,6 +2153,7 @@ dependencies = [
"static_assertions", "static_assertions",
"substrate-wasm-builder", "substrate-wasm-builder",
"testnet-parachains-constants", "testnet-parachains-constants",
"tuplex",
] ]
[[package]] [[package]]
...@@ -2222,7 +2223,6 @@ dependencies = [ ...@@ -2222,7 +2223,6 @@ dependencies = [
"pallet-message-queue", "pallet-message-queue",
"pallet-xcm", "pallet-xcm",
"parachains-common", "parachains-common",
"parity-scale-codec",
"rococo-westend-system-emulated-network", "rococo-westend-system-emulated-network",
"sp-runtime", "sp-runtime",
"staging-xcm", "staging-xcm",
...@@ -2312,6 +2312,7 @@ dependencies = [ ...@@ -2312,6 +2312,7 @@ dependencies = [
"static_assertions", "static_assertions",
"substrate-wasm-builder", "substrate-wasm-builder",
"testnet-parachains-constants", "testnet-parachains-constants",
"tuplex",
"westend-runtime-constants", "westend-runtime-constants",
] ]
...@@ -2350,6 +2351,7 @@ dependencies = [ ...@@ -2350,6 +2351,7 @@ dependencies = [
"staging-xcm", "staging-xcm",
"staging-xcm-builder", "staging-xcm-builder",
"static_assertions", "static_assertions",
"tuplex",
] ]
[[package]] [[package]]
...@@ -11777,7 +11779,6 @@ dependencies = [ ...@@ -11777,7 +11779,6 @@ dependencies = [
"polkadot-primitives", "polkadot-primitives",
"polkadot-runtime-common", "polkadot-runtime-common",
"scale-info", "scale-info",
"sp-core",
"sp-io", "sp-io",
"sp-runtime", "sp-runtime",
"sp-std 14.0.0", "sp-std 14.0.0",
...@@ -13018,6 +13019,7 @@ dependencies = [ ...@@ -13018,6 +13019,7 @@ dependencies = [
"polkadot-overseer", "polkadot-overseer",
"polkadot-primitives", "polkadot-primitives",
"polkadot-primitives-test-helpers", "polkadot-primitives-test-helpers",
"polkadot-subsystem-bench",
"rand 0.8.5", "rand 0.8.5",
"rand_chacha 0.3.1", "rand_chacha 0.3.1",
"rand_core 0.6.4", "rand_core 0.6.4",
...@@ -14348,7 +14350,6 @@ dependencies = [ ...@@ -14348,7 +14350,6 @@ dependencies = [
name = "polkadot-test-runtime" name = "polkadot-test-runtime"
version = "1.0.0" version = "1.0.0"
dependencies = [ dependencies = [
"bitvec",
"frame-election-provider-support", "frame-election-provider-support",
"frame-executive", "frame-executive",
"frame-support", "frame-support",
...@@ -14373,16 +14374,12 @@ dependencies = [ ...@@ -14373,16 +14374,12 @@ dependencies = [
"pallet-vesting", "pallet-vesting",
"pallet-xcm", "pallet-xcm",
"parity-scale-codec", "parity-scale-codec",
"polkadot-parachain-primitives",
"polkadot-primitives", "polkadot-primitives",
"polkadot-runtime-common", "polkadot-runtime-common",
"polkadot-runtime-parachains", "polkadot-runtime-parachains",
"rustc-hex",
"scale-info", "scale-info",
"serde", "serde",
"serde_derive",
"serde_json", "serde_json",
"smallvec",
"sp-api", "sp-api",
"sp-authority-discovery", "sp-authority-discovery",
"sp-block-builder", "sp-block-builder",
...@@ -21273,11 +21270,8 @@ version = "1.0.0" ...@@ -21273,11 +21270,8 @@ version = "1.0.0"
dependencies = [ dependencies = [
"frame-support", "frame-support",
"polkadot-primitives", "polkadot-primitives",
"polkadot-runtime-common",
"smallvec", "smallvec",
"sp-core",
"sp-runtime", "sp-runtime",
"sp-weights",
] ]
[[package]] [[package]]
...@@ -22055,6 +22049,12 @@ dependencies = [ ...@@ -22055,6 +22049,12 @@ dependencies = [
"utf-8", "utf-8",
] ]
[[package]]
name = "tuplex"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "676ac81d5454c4dcf37955d34fa8626ede3490f744b86ca14a7b90168d2a08aa"
[[package]] [[package]]
name = "twox-hash" name = "twox-hash"
version = "1.6.3" version = "1.6.3"
......
...@@ -16,6 +16,7 @@ hash-db = { version = "0.16.0", default-features = false } ...@@ -16,6 +16,7 @@ hash-db = { version = "0.16.0", default-features = false }
log = { workspace = true } log = { workspace = true }
scale-info = { version = "2.11.1", default-features = false, features = ["derive"] } scale-info = { version = "2.11.1", default-features = false, features = ["derive"] }
static_assertions = { version = "1.1", optional = true } static_assertions = { version = "1.1", optional = true }
tuplex = { version = "0.1", default-features = false }
# Bridge dependencies # Bridge dependencies
...@@ -82,6 +83,7 @@ std = [ ...@@ -82,6 +83,7 @@ std = [
"sp-runtime/std", "sp-runtime/std",
"sp-std/std", "sp-std/std",
"sp-trie/std", "sp-trie/std",
"tuplex/std",
"xcm-builder/std", "xcm-builder/std",
"xcm/std", "xcm/std",
] ]
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
//! single message with nonce `N`, then the transaction with nonces `N..=N+100` will //! single message with nonce `N`, then the transaction with nonces `N..=N+100` will
//! be rejected. This can lower bridge throughput down to one message per block. //! be rejected. This can lower bridge throughput down to one message per block.
use bp_messages::MessageNonce;
use frame_support::traits::Get; use frame_support::traits::Get;
use sp_runtime::transaction_validity::TransactionPriority; use sp_runtime::transaction_validity::TransactionPriority;
...@@ -30,16 +29,19 @@ use sp_runtime::transaction_validity::TransactionPriority; ...@@ -30,16 +29,19 @@ use sp_runtime::transaction_validity::TransactionPriority;
#[allow(unused_imports)] #[allow(unused_imports)]
pub use integrity_tests::*; pub use integrity_tests::*;
/// Compute priority boost for message delivery transaction that delivers /// We'll deal with different bridge items here - messages, headers, ...
/// given number of messages. /// To avoid being too verbose with generic code, let's just define a separate alias.
pub fn compute_priority_boost<PriorityBoostPerMessage>( pub type ItemCount = u64;
messages: MessageNonce,
) -> TransactionPriority /// Compute priority boost for transaction that brings given number of bridge
/// items (messages, headers, ...), when every additional item adds `PriorityBoostPerItem`
/// to transaction priority.
pub fn compute_priority_boost<PriorityBoostPerItem>(n_items: ItemCount) -> TransactionPriority
where where
PriorityBoostPerMessage: Get<TransactionPriority>, PriorityBoostPerItem: Get<TransactionPriority>,
{ {
// we don't want any boost for transaction with single message => minus one // we don't want any boost for transaction with single (additional) item => minus one
PriorityBoostPerMessage::get().saturating_mul(messages.saturating_sub(1)) PriorityBoostPerItem::get().saturating_mul(n_items.saturating_sub(1))
} }
#[cfg(not(feature = "integrity-test"))] #[cfg(not(feature = "integrity-test"))]
...@@ -47,7 +49,8 @@ mod integrity_tests {} ...@@ -47,7 +49,8 @@ mod integrity_tests {}
#[cfg(feature = "integrity-test")] #[cfg(feature = "integrity-test")]
mod integrity_tests { mod integrity_tests {
use super::compute_priority_boost; use super::{compute_priority_boost, ItemCount};
use crate::extensions::refund_relayer_extension::RefundableParachainId;
use bp_messages::MessageNonce; use bp_messages::MessageNonce;
use bp_runtime::PreComputedSize; use bp_runtime::PreComputedSize;
...@@ -55,7 +58,6 @@ mod integrity_tests { ...@@ -55,7 +58,6 @@ mod integrity_tests {
dispatch::{DispatchClass, DispatchInfo, Pays, PostDispatchInfo}, dispatch::{DispatchClass, DispatchInfo, Pays, PostDispatchInfo},
traits::Get, traits::Get,
}; };
use pallet_bridge_messages::WeightInfoExt;
use pallet_transaction_payment::OnChargeTransaction; use pallet_transaction_payment::OnChargeTransaction;
use sp_runtime::{ use sp_runtime::{
traits::{Dispatchable, UniqueSaturatedInto, Zero}, traits::{Dispatchable, UniqueSaturatedInto, Zero},
...@@ -68,37 +70,33 @@ mod integrity_tests { ...@@ -68,37 +70,33 @@ mod integrity_tests {
T, T,
>>::Balance; >>::Balance;
/// Ensures that the value of `PriorityBoostPerMessage` matches the value of /// Ensures that the value of `PriorityBoostPerItem` matches the value of
/// `tip_boost_per_message`. /// `tip_boost_per_item`.
/// ///
/// We want two transactions, `TX1` with `N` messages and `TX2` with `N+1` messages, have almost /// We want two transactions, `TX1` with `N` items and `TX2` with `N+1` items, have almost
/// the same priority if we'll add `tip_boost_per_message` tip to the `TX1`. We want to be sure /// the same priority if we'll add `tip_boost_per_item` tip to the `TX1`. We want to be sure
/// that if we add plain `PriorityBoostPerMessage` priority to `TX1`, the priority will be close /// that if we add plain `PriorityBoostPerItem` priority to `TX1`, the priority will be close
/// to `TX2` as well. /// to `TX2` as well.
pub fn ensure_priority_boost_is_sane<Runtime, MessagesInstance, PriorityBoostPerMessage>( fn ensure_priority_boost_is_sane<PriorityBoostPerItem, Balance>(
tip_boost_per_message: BalanceOf<Runtime>, param_name: &str,
max_items: ItemCount,
tip_boost_per_item: Balance,
estimate_priority: impl Fn(ItemCount, Balance) -> TransactionPriority,
) where ) where
Runtime: PriorityBoostPerItem: Get<TransactionPriority>,
pallet_transaction_payment::Config + pallet_bridge_messages::Config<MessagesInstance>, ItemCount: UniqueSaturatedInto<Balance>,
MessagesInstance: 'static, Balance: FixedPointOperand + Zero,
PriorityBoostPerMessage: Get<TransactionPriority>,
Runtime::RuntimeCall: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
BalanceOf<Runtime>: Send + Sync + FixedPointOperand,
{ {
let priority_boost_per_message = PriorityBoostPerMessage::get(); let priority_boost_per_item = PriorityBoostPerItem::get();
let maximal_messages_in_delivery_transaction = for n_items in 1..=max_items {
Runtime::MaxUnconfirmedMessagesAtInboundLane::get(); let base_priority = estimate_priority(n_items, Zero::zero());
for messages in 1..=maximal_messages_in_delivery_transaction { let priority_boost = compute_priority_boost::<PriorityBoostPerItem>(n_items);
let base_priority = estimate_message_delivery_transaction_priority::< let priority_with_boost = base_priority
Runtime, .checked_add(priority_boost)
MessagesInstance, .expect("priority overflow: try lowering `max_items` or `tip_boost_per_item`?");
>(messages, Zero::zero());
let priority_boost = compute_priority_boost::<PriorityBoostPerMessage>(messages);
let priority_with_boost = base_priority + priority_boost;
let tip = tip_boost_per_message.saturating_mul((messages - 1).unique_saturated_into()); let tip = tip_boost_per_item.saturating_mul((n_items - 1).unique_saturated_into());
let priority_with_tip = let priority_with_tip = estimate_priority(1, tip);
estimate_message_delivery_transaction_priority::<Runtime, MessagesInstance>(1, tip);
const ERROR_MARGIN: TransactionPriority = 5; // 5% const ERROR_MARGIN: TransactionPriority = 5; // 5%
if priority_with_boost.abs_diff(priority_with_tip).saturating_mul(100) / if priority_with_boost.abs_diff(priority_with_tip).saturating_mul(100) /
...@@ -106,46 +104,252 @@ mod integrity_tests { ...@@ -106,46 +104,252 @@ mod integrity_tests {
ERROR_MARGIN ERROR_MARGIN
{ {
panic!( panic!(
"The PriorityBoostPerMessage value ({}) must be fixed to: {}", "The {param_name} value ({}) must be fixed to: {}",
priority_boost_per_message, priority_boost_per_item,
compute_priority_boost_per_message::<Runtime, MessagesInstance>( compute_priority_boost_per_item(
tip_boost_per_message max_items,
tip_boost_per_item,
estimate_priority
), ),
); );
} }
} }
} }
/// Compute priority boost that we give to message delivery transaction for additional message. /// Compute priority boost that we give to bridge transaction for every
/// additional bridge item.
#[cfg(feature = "integrity-test")] #[cfg(feature = "integrity-test")]
fn compute_priority_boost_per_message<Runtime, MessagesInstance>( fn compute_priority_boost_per_item<Balance>(
tip_boost_per_message: BalanceOf<Runtime>, max_items: ItemCount,
tip_boost_per_item: Balance,
estimate_priority: impl Fn(ItemCount, Balance) -> TransactionPriority,
) -> TransactionPriority
where
ItemCount: UniqueSaturatedInto<Balance>,
Balance: FixedPointOperand + Zero,
{
// estimate priority of transaction that delivers one item and has large tip
let small_with_tip_priority =
estimate_priority(1, tip_boost_per_item.saturating_mul(max_items.saturated_into()));
// estimate priority of transaction that delivers maximal number of items, but has no tip
let large_without_tip_priority = estimate_priority(max_items, Zero::zero());
small_with_tip_priority
.saturating_sub(large_without_tip_priority)
.saturating_div(max_items - 1)
}
/// Computations, specific to bridge relay chains transactions.
pub mod per_relay_header {
use super::*;
use bp_header_chain::{
max_expected_submit_finality_proof_arguments_size, ChainWithGrandpa,
};
use pallet_bridge_grandpa::WeightInfoExt;
/// Ensures that the value of `PriorityBoostPerHeader` matches the value of
/// `tip_boost_per_header`.
///
/// We want two transactions, `TX1` with `N` headers and `TX2` with `N+1` headers, have
/// almost the same priority if we'll add `tip_boost_per_header` tip to the `TX1`. We want
/// to be sure that if we add plain `PriorityBoostPerHeader` priority to `TX1`, the priority
/// will be close to `TX2` as well.
pub fn ensure_priority_boost_is_sane<Runtime, GrandpaInstance, PriorityBoostPerHeader>(
tip_boost_per_header: BalanceOf<Runtime>,
) where
Runtime:
pallet_transaction_payment::Config + pallet_bridge_grandpa::Config<GrandpaInstance>,
GrandpaInstance: 'static,
PriorityBoostPerHeader: Get<TransactionPriority>,
Runtime::RuntimeCall: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
BalanceOf<Runtime>: Send + Sync + FixedPointOperand,
{
// the meaning of `max_items` here is different when comparing with message
// transactions - with messages we have a strict limit on maximal number of
// messages we can fit into a single transaction. With headers, current best
// header may be improved by any "number of items". But this number is only
// used to verify priority boost, so it should be fine to select this arbitrary
// value - it SHALL NOT affect any value, it just adds more tests for the value.
let maximal_improved_by = 4_096;
super::ensure_priority_boost_is_sane::<PriorityBoostPerHeader, BalanceOf<Runtime>>(
"PriorityBoostPerRelayHeader",
maximal_improved_by,
tip_boost_per_header,
|_n_headers, tip| {
estimate_relay_header_submit_transaction_priority::<Runtime, GrandpaInstance>(
tip,
)
},
);
}
/// Estimate relay header delivery transaction priority.
#[cfg(feature = "integrity-test")]
fn estimate_relay_header_submit_transaction_priority<Runtime, GrandpaInstance>(
tip: BalanceOf<Runtime>,
) -> TransactionPriority ) -> TransactionPriority
where where
Runtime: Runtime:
pallet_transaction_payment::Config + pallet_bridge_messages::Config<MessagesInstance>, pallet_transaction_payment::Config + pallet_bridge_grandpa::Config<GrandpaInstance>,
GrandpaInstance: 'static,
Runtime::RuntimeCall: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
BalanceOf<Runtime>: Send + Sync + FixedPointOperand,
{
// just an estimation of extra transaction bytes that are added to every transaction
// (including signature, signed extensions extra and etc + in our case it includes
// all call arguments except the proof itself)
let base_tx_size = 512;
// let's say we are relaying largest relay chain headers
let tx_call_size = max_expected_submit_finality_proof_arguments_size::<
Runtime::BridgedChain,
>(true, Runtime::BridgedChain::MAX_AUTHORITIES_COUNT * 2 / 3 + 1);
// finally we are able to estimate transaction size and weight
let transaction_size = base_tx_size.saturating_add(tx_call_size);
let transaction_weight = Runtime::WeightInfo::submit_finality_proof_weight(
Runtime::BridgedChain::MAX_AUTHORITIES_COUNT * 2 / 3 + 1,
Runtime::BridgedChain::REASONABLE_HEADERS_IN_JUSTIFICATION_ANCESTRY,
);
pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::get_priority(
&DispatchInfo {
weight: transaction_weight,
class: DispatchClass::Normal,
pays_fee: Pays::Yes,
},
transaction_size as _,
tip,
Zero::zero(),
)
}
}
/// Computations, specific to bridge parachains transactions.
pub mod per_parachain_header {
use super::*;
use bp_runtime::Parachain;
use pallet_bridge_parachains::WeightInfoExt;
/// Ensures that the value of `PriorityBoostPerHeader` matches the value of
/// `tip_boost_per_header`.
///
/// We want two transactions, `TX1` with `N` headers and `TX2` with `N+1` headers, have
/// almost the same priority if we'll add `tip_boost_per_header` tip to the `TX1`. We want
/// to be sure that if we add plain `PriorityBoostPerHeader` priority to `TX1`, the priority
/// will be close to `TX2` as well.
pub fn ensure_priority_boost_is_sane<Runtime, RefundableParachain, PriorityBoostPerHeader>(
tip_boost_per_header: BalanceOf<Runtime>,
) where
Runtime: pallet_transaction_payment::Config
+ pallet_bridge_parachains::Config<RefundableParachain::Instance>,
RefundableParachain: RefundableParachainId,
PriorityBoostPerHeader: Get<TransactionPriority>,
Runtime::RuntimeCall: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
BalanceOf<Runtime>: Send + Sync + FixedPointOperand,
{
// the meaning of `max_items` here is different when comparing with message
// transactions - with messages we have a strict limit on maximal number of
// messages we can fit into a single transaction. With headers, current best
// header may be improved by any "number of items". But this number is only
// used to verify priority boost, so it should be fine to select this arbitrary
// value - it SHALL NOT affect any value, it just adds more tests for the value.
let maximal_improved_by = 4_096;
super::ensure_priority_boost_is_sane::<PriorityBoostPerHeader, BalanceOf<Runtime>>(
"PriorityBoostPerParachainHeader",
maximal_improved_by,
tip_boost_per_header,
|_n_headers, tip| {
estimate_parachain_header_submit_transaction_priority::<
Runtime,
RefundableParachain,
>(tip)
},
);
}
/// Estimate parachain header delivery transaction priority.
#[cfg(feature = "integrity-test")]
fn estimate_parachain_header_submit_transaction_priority<Runtime, RefundableParachain>(
tip: BalanceOf<Runtime>,
) -> TransactionPriority
where
Runtime: pallet_transaction_payment::Config
+ pallet_bridge_parachains::Config<RefundableParachain::Instance>,
RefundableParachain: RefundableParachainId,
Runtime::RuntimeCall: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
BalanceOf<Runtime>: Send + Sync + FixedPointOperand,
{
// just an estimation of extra transaction bytes that are added to every transaction
// (including signature, signed extensions extra and etc + in our case it includes
// all call arguments except the proof itself)
let base_tx_size = 512;
// let's say we are relaying largest parachain headers and proof takes some more bytes
let tx_call_size = <Runtime as pallet_bridge_parachains::Config<
RefundableParachain::Instance,
>>::WeightInfo::expected_extra_storage_proof_size()
.saturating_add(RefundableParachain::BridgedChain::MAX_HEADER_SIZE);
// finally we are able to estimate transaction size and weight
let transaction_size = base_tx_size.saturating_add(tx_call_size);
let transaction_weight = <Runtime as pallet_bridge_parachains::Config<
RefundableParachain::Instance,
>>::WeightInfo::submit_parachain_heads_weight(
Runtime::DbWeight::get(),
&PreComputedSize(transaction_size as _),
// just one parachain - all other submissions won't receive any boost
1,
);
pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::get_priority(
&DispatchInfo {
weight: transaction_weight,
class: DispatchClass::Normal,
pays_fee: Pays::Yes,
},
transaction_size as _,
tip,
Zero::zero(),
)
}
}
/// Computations, specific to bridge messages transactions.
pub mod per_message {
use super::*;
use pallet_bridge_messages::WeightInfoExt;
/// Ensures that the value of `PriorityBoostPerMessage` matches the value of
/// `tip_boost_per_message`.
///
/// We want two transactions, `TX1` with `N` messages and `TX2` with `N+1` messages, have
/// almost the same priority if we'll add `tip_boost_per_message` tip to the `TX1`. We want
/// to be sure that if we add plain `PriorityBoostPerMessage` priority to `TX1`, the
/// priority will be close to `TX2` as well.
pub fn ensure_priority_boost_is_sane<Runtime, MessagesInstance, PriorityBoostPerMessage>(
tip_boost_per_message: BalanceOf<Runtime>,
) where
Runtime: pallet_transaction_payment::Config
+ pallet_bridge_messages::Config<MessagesInstance>,
MessagesInstance: 'static, MessagesInstance: 'static,
PriorityBoostPerMessage: Get<TransactionPriority>,
Runtime::RuntimeCall: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>, Runtime::RuntimeCall: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
BalanceOf<Runtime>: Send + Sync + FixedPointOperand, BalanceOf<Runtime>: Send + Sync + FixedPointOperand,
{ {
// estimate priority of transaction that delivers one message and has large tip
let maximal_messages_in_delivery_transaction = let maximal_messages_in_delivery_transaction =
Runtime::MaxUnconfirmedMessagesAtInboundLane::get(); Runtime::MaxUnconfirmedMessagesAtInboundLane::get();
let small_with_tip_priority = super::ensure_priority_boost_is_sane::<PriorityBoostPerMessage, BalanceOf<Runtime>>(
"PriorityBoostPerMessage",
maximal_messages_in_delivery_transaction,
tip_boost_per_message,
|n_messages, tip| {
estimate_message_delivery_transaction_priority::<Runtime, MessagesInstance>( estimate_message_delivery_transaction_priority::<Runtime, MessagesInstance>(
1, n_messages, tip,
tip_boost_per_message )
.saturating_mul(maximal_messages_in_delivery_transaction.saturated_into()), },
); );
// estimate priority of transaction that delivers maximal number of messages, but has no tip
let large_without_tip_priority = estimate_message_delivery_transaction_priority::<
Runtime,
MessagesInstance,
>(maximal_messages_in_delivery_transaction, Zero::zero());
small_with_tip_priority
.saturating_sub(large_without_tip_priority)
.saturating_div(maximal_messages_in_delivery_transaction - 1)
} }
/// Estimate message delivery transaction priority. /// Estimate message delivery transaction priority.
...@@ -155,8 +359,8 @@ mod integrity_tests { ...@@ -155,8 +359,8 @@ mod integrity_tests {
tip: BalanceOf<Runtime>, tip: BalanceOf<Runtime>,
) -> TransactionPriority ) -> TransactionPriority
where where
Runtime: Runtime: pallet_transaction_payment::Config
pallet_transaction_payment::Config + pallet_bridge_messages::Config<MessagesInstance>, + pallet_bridge_messages::Config<MessagesInstance>,
MessagesInstance: 'static, MessagesInstance: 'static,
Runtime::RuntimeCall: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>, Runtime::RuntimeCall: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
BalanceOf<Runtime>: Send + Sync + FixedPointOperand, BalanceOf<Runtime>: Send + Sync + FixedPointOperand,
...@@ -165,15 +369,15 @@ mod integrity_tests { ...@@ -165,15 +369,15 @@ mod integrity_tests {
// (including signature, signed extensions extra and etc + in our case it includes // (including signature, signed extensions extra and etc + in our case it includes
// all call arguments except the proof itself) // all call arguments except the proof itself)
let base_tx_size = 512; let base_tx_size = 512;
// let's say we are relaying similar small messages and for every message we add more trie // let's say we are relaying similar small messages and for every message we add more
// nodes to the proof (x0.5 because we expect some nodes to be reused) // trie nodes to the proof (x0.5 because we expect some nodes to be reused)
let estimated_message_size = 512; let estimated_message_size = 512;
// let's say all our messages have the same dispatch weight // let's say all our messages have the same dispatch weight
let estimated_message_dispatch_weight = let estimated_message_dispatch_weight =
Runtime::WeightInfo::message_dispatch_weight(estimated_message_size); Runtime::WeightInfo::message_dispatch_weight(estimated_message_size);
// messages proof argument size is (for every message) messages size + some additional // messages proof argument size is (for every message) messages size + some additional
// trie nodes. Some of them are reused by different messages, so let's take 2/3 of default // trie nodes. Some of them are reused by different messages, so let's take 2/3 of
// "overhead" constant // default "overhead" constant
let messages_proof_size = Runtime::WeightInfo::expected_extra_storage_proof_size() let messages_proof_size = Runtime::WeightInfo::expected_extra_storage_proof_size()
.saturating_mul(2) .saturating_mul(2)
.saturating_div(3) .saturating_div(3)
...@@ -200,3 +404,4 @@ mod integrity_tests { ...@@ -200,3 +404,4 @@ mod integrity_tests {
) )
} }
} }
}
...@@ -183,7 +183,8 @@ impl pallet_transaction_payment::Config for TestRuntime { ...@@ -183,7 +183,8 @@ impl pallet_transaction_payment::Config for TestRuntime {
impl pallet_bridge_grandpa::Config for TestRuntime { impl pallet_bridge_grandpa::Config for TestRuntime {
type RuntimeEvent = RuntimeEvent; type RuntimeEvent = RuntimeEvent;
type BridgedChain = BridgedUnderlyingChain; type BridgedChain = BridgedUnderlyingChain;
type MaxFreeMandatoryHeadersPerBlock = ConstU32<4>; type MaxFreeHeadersPerBlock = ConstU32<4>;
type FreeHeadersInterval = ConstU32<1_024>;
type HeadersToKeep = ConstU32<8>; type HeadersToKeep = ConstU32<8>;
type WeightInfo = pallet_bridge_grandpa::weights::BridgeWeight<TestRuntime>; type WeightInfo = pallet_bridge_grandpa::weights::BridgeWeight<TestRuntime>;
} }
...@@ -406,6 +407,7 @@ impl Chain for BridgedUnderlyingParachain { ...@@ -406,6 +407,7 @@ impl Chain for BridgedUnderlyingParachain {
impl Parachain for BridgedUnderlyingParachain { impl Parachain for BridgedUnderlyingParachain {
const PARACHAIN_ID: u32 = 42; const PARACHAIN_ID: u32 = 42;
const MAX_HEADER_SIZE: u32 = 1_024;
} }
/// The other, bridged chain, used in tests. /// The other, bridged chain, used in tests.
......
...@@ -39,6 +39,9 @@ use frame_support::{ ...@@ -39,6 +39,9 @@ use frame_support::{
use frame_system::limits; use frame_system::limits;
use sp_std::time::Duration; use sp_std::time::Duration;
/// Maximal bridge hub header size.
pub const MAX_BRIDGE_HUB_HEADER_SIZE: u32 = 4_096;
/// Average block interval in Cumulus-based parachains. /// Average block interval in Cumulus-based parachains.
/// ///
/// Corresponds to the `MILLISECS_PER_BLOCK` from `parachains_common` crate. /// Corresponds to the `MILLISECS_PER_BLOCK` from `parachains_common` crate.
......
...@@ -62,6 +62,7 @@ impl Chain for BridgeHubKusama { ...@@ -62,6 +62,7 @@ impl Chain for BridgeHubKusama {
impl Parachain for BridgeHubKusama { impl Parachain for BridgeHubKusama {
const PARACHAIN_ID: u32 = BRIDGE_HUB_KUSAMA_PARACHAIN_ID; const PARACHAIN_ID: u32 = BRIDGE_HUB_KUSAMA_PARACHAIN_ID;
const MAX_HEADER_SIZE: u32 = MAX_BRIDGE_HUB_HEADER_SIZE;
} }
impl ChainWithMessages for BridgeHubKusama { impl ChainWithMessages for BridgeHubKusama {
......
...@@ -59,6 +59,7 @@ impl Chain for BridgeHubPolkadot { ...@@ -59,6 +59,7 @@ impl Chain for BridgeHubPolkadot {
impl Parachain for BridgeHubPolkadot { impl Parachain for BridgeHubPolkadot {
const PARACHAIN_ID: u32 = BRIDGE_HUB_POLKADOT_PARACHAIN_ID; const PARACHAIN_ID: u32 = BRIDGE_HUB_POLKADOT_PARACHAIN_ID;
const MAX_HEADER_SIZE: u32 = MAX_BRIDGE_HUB_HEADER_SIZE;
} }
impl ChainWithMessages for BridgeHubPolkadot { impl ChainWithMessages for BridgeHubPolkadot {
......
...@@ -59,6 +59,7 @@ impl Chain for BridgeHubRococo { ...@@ -59,6 +59,7 @@ impl Chain for BridgeHubRococo {
impl Parachain for BridgeHubRococo { impl Parachain for BridgeHubRococo {
const PARACHAIN_ID: u32 = BRIDGE_HUB_ROCOCO_PARACHAIN_ID; const PARACHAIN_ID: u32 = BRIDGE_HUB_ROCOCO_PARACHAIN_ID;
const MAX_HEADER_SIZE: u32 = MAX_BRIDGE_HUB_HEADER_SIZE;
} }
impl ChainWithMessages for BridgeHubRococo { impl ChainWithMessages for BridgeHubRococo {
...@@ -103,9 +104,9 @@ frame_support::parameter_types! { ...@@ -103,9 +104,9 @@ frame_support::parameter_types! {
/// Transaction fee that is paid at the Rococo BridgeHub for delivering single inbound message. /// 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%`) /// (initially was calculated by test `BridgeHubRococo::can_calculate_fee_for_complex_message_delivery_transaction` + `33%`)
pub const BridgeHubRococoBaseDeliveryFeeInRocs: u128 = 5_651_581_649; pub const BridgeHubRococoBaseDeliveryFeeInRocs: u128 = 314_037_860;
/// Transaction fee that is paid at the Rococo BridgeHub for delivering single outbound message confirmation. /// 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%`) /// (initially was calculated by test `BridgeHubRococo::can_calculate_fee_for_complex_message_confirmation_transaction` + `33%`)
pub const BridgeHubRococoBaseConfirmationFeeInRocs: u128 = 5_380_901_781; pub const BridgeHubRococoBaseConfirmationFeeInRocs: u128 = 57_414_813;
} }
...@@ -58,6 +58,7 @@ impl Chain for BridgeHubWestend { ...@@ -58,6 +58,7 @@ impl Chain for BridgeHubWestend {
impl Parachain for BridgeHubWestend { impl Parachain for BridgeHubWestend {
const PARACHAIN_ID: u32 = BRIDGE_HUB_WESTEND_PARACHAIN_ID; const PARACHAIN_ID: u32 = BRIDGE_HUB_WESTEND_PARACHAIN_ID;
const MAX_HEADER_SIZE: u32 = MAX_BRIDGE_HUB_HEADER_SIZE;
} }
impl ChainWithMessages for BridgeHubWestend { impl ChainWithMessages for BridgeHubWestend {
...@@ -93,10 +94,10 @@ frame_support::parameter_types! { ...@@ -93,10 +94,10 @@ frame_support::parameter_types! {
pub const BridgeHubWestendBaseXcmFeeInWnds: u128 = 17_756_830_000; pub const BridgeHubWestendBaseXcmFeeInWnds: u128 = 17_756_830_000;
/// Transaction fee that is paid at the Westend BridgeHub for delivering single inbound message. /// 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%`) /// (initially was calculated by test `BridgeHubWestend::can_calculate_fee_for_standalone_message_delivery_transaction` + `33%`)
pub const BridgeHubWestendBaseDeliveryFeeInWnds: u128 = 1_695_489_961_344; pub const BridgeHubWestendBaseDeliveryFeeInWnds: u128 = 94_211_536_452;
/// Transaction fee that is paid at the Westend BridgeHub for delivering single outbound message confirmation. /// 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%`) /// (initially was calculated by test `BridgeHubWestend::can_calculate_fee_for_standalone_message_confirmation_transaction` + `33%`)
pub const BridgeHubWestendBaseConfirmationFeeInWnds: u128 = 1_618_309_961_344; pub const BridgeHubWestendBaseConfirmationFeeInWnds: u128 = 17_224_486_452;
} }
...@@ -67,6 +67,8 @@ pub const PARAS_PALLET_NAME: &str = "Paras"; ...@@ -67,6 +67,8 @@ pub const PARAS_PALLET_NAME: &str = "Paras";
/// Name of the With-Kusama GRANDPA pallet instance that is deployed at bridged chains. /// Name of the With-Kusama GRANDPA pallet instance that is deployed at bridged chains.
pub const WITH_KUSAMA_GRANDPA_PALLET_NAME: &str = "BridgeKusamaGrandpa"; pub const WITH_KUSAMA_GRANDPA_PALLET_NAME: &str = "BridgeKusamaGrandpa";
/// Name of the With-Kusama parachains pallet instance that is deployed at bridged chains.
pub const WITH_KUSAMA_BRIDGE_PARACHAINS_PALLET_NAME: &str = "BridgeKusamaParachains";
/// Maximal size of encoded `bp_parachains::ParaStoredHeaderData` structure among all Polkadot /// Maximal size of encoded `bp_parachains::ParaStoredHeaderData` structure among all Polkadot
/// parachains. /// parachains.
......
...@@ -69,6 +69,8 @@ pub const PARAS_PALLET_NAME: &str = "Paras"; ...@@ -69,6 +69,8 @@ pub const PARAS_PALLET_NAME: &str = "Paras";
/// Name of the With-Polkadot GRANDPA pallet instance that is deployed at bridged chains. /// Name of the With-Polkadot GRANDPA pallet instance that is deployed at bridged chains.
pub const WITH_POLKADOT_GRANDPA_PALLET_NAME: &str = "BridgePolkadotGrandpa"; pub const WITH_POLKADOT_GRANDPA_PALLET_NAME: &str = "BridgePolkadotGrandpa";
/// Name of the With-Polkadot parachains pallet instance that is deployed at bridged chains.
pub const WITH_POLKADOT_BRIDGE_PARACHAINS_PALLET_NAME: &str = "BridgePolkadotParachains";
/// Maximal size of encoded `bp_parachains::ParaStoredHeaderData` structure among all Polkadot /// Maximal size of encoded `bp_parachains::ParaStoredHeaderData` structure among all Polkadot
/// parachains. /// parachains.
......