Skip to content

Commit

Permalink
refund relayer if parachain head has not been updated (paritytech#1528)
Browse files Browse the repository at this point in the history
  • Loading branch information
svyatonik authored and serban300 committed Apr 8, 2024
1 parent 266946f commit 76be3f8
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 6 deletions.
33 changes: 27 additions & 6 deletions bridges/modules/parachains/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ pub mod pallet {
&parachain_heads_proof,
parachains.len() as _,
);

pallet_bridge_grandpa::Pallet::<T, T::BridgesGrandpaPalletInstance>::parse_finalized_storage_proof(
relay_block_hash,
sp_trie::StorageProof::new(parachain_heads_proof.0),
Expand Down Expand Up @@ -293,7 +294,7 @@ pub mod pallet {
continue;
}

let prune_happened: Result<_, ()> = BestParaHeads::<T, I>::try_mutate(parachain, |stored_best_head| {
let update_result: Result<_, ()> = BestParaHeads::<T, I>::try_mutate(parachain, |stored_best_head| {
let artifacts = Pallet::<T, I>::update_parachain_head(
parachain,
stored_best_head.take(),
Expand All @@ -305,7 +306,14 @@ pub mod pallet {
Ok(artifacts.prune_happened)
});

if matches!(prune_happened, Err(_) | Ok(false)) {
// we're refunding weight if update has not happened and if pruning has not happened
let is_update_happened = matches!(update_result, Ok(_));
if !is_update_happened {
actual_weight = actual_weight
.saturating_sub(WeightInfoOf::<T, I>::parachain_head_storage_write_weight(T::DbWeight::get()));
}
let is_prune_happened = matches!(update_result, Ok(true));
if !is_prune_happened {
actual_weight = actual_weight
.saturating_sub(WeightInfoOf::<T, I>::parachain_head_pruning_weight(T::DbWeight::get()));
}
Expand Down Expand Up @@ -538,6 +546,8 @@ mod tests {
};

type BridgesGrandpaPalletInstance = pallet_bridge_grandpa::Instance1;
type WeightInfo = <TestRuntime as Config>::WeightInfo;
type DbWeight = <TestRuntime as frame_system::Config>::DbWeight;

fn initialize(state_root: RelayBlockHash) {
pallet_bridge_grandpa::Pallet::<TestRuntime, BridgesGrandpaPalletInstance>::initialize(
Expand Down Expand Up @@ -675,12 +685,16 @@ mod tests {
initialize(state_root);

// we're trying to update heads of parachains 1, 2 and 3
assert_ok!(Pallet::<TestRuntime>::submit_parachain_heads(
let expected_weight =
WeightInfo::submit_parachain_heads_weight(DbWeight::get(), &proof, 2);
let result = Pallet::<TestRuntime>::submit_parachain_heads(
Origin::signed(1),
(0, test_relay_header(0, state_root).hash()),
parachains,
proof,
),);
);
assert_ok!(result);
assert_eq!(result.expect("checked above").actual_weight, Some(expected_weight));

// but only 1 and 2 are updated, because proof is missing head of parachain#2
assert_eq!(BestParaHeads::<TestRuntime>::get(ParaId(1)), Some(initial_best_head(1)));
Expand Down Expand Up @@ -768,13 +782,20 @@ mod tests {
run_test(|| {
// start with relay block #0 and try to import head#5 of parachain#1 and untracked
// parachain
let expected_weight =
WeightInfo::submit_parachain_heads_weight(DbWeight::get(), &proof, 3)
.saturating_sub(WeightInfo::parachain_head_storage_write_weight(
DbWeight::get(),
));
initialize(state_root);
assert_ok!(Pallet::<TestRuntime>::submit_parachain_heads(
let result = Pallet::<TestRuntime>::submit_parachain_heads(
Origin::signed(1),
(0, test_relay_header(0, state_root).hash()),
parachains,
proof,
));
);
assert_ok!(result);
assert_eq!(result.expect("checked above").actual_weight, Some(expected_weight));
assert_eq!(
BestParaHeads::<TestRuntime>::get(ParaId(1)),
Some(BestParaHead {
Expand Down
11 changes: 11 additions & 0 deletions bridges/modules/parachains/src/weights_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,17 @@ pub trait WeightInfoExt: WeightInfo {
base_weight.saturating_add(proof_size_overhead).saturating_add(pruning_weight)
}

/// Returns weight of single parachain head storage update.
///
/// This weight only includes db write operations that happens if parachain head is actually
/// updated. All extra weights (weight of storage proof validation, additional checks, ...) is
/// not included.
fn parachain_head_storage_write_weight(db_weight: RuntimeDbWeight) -> Weight {
// it's just a couple of operations - we need to write the hash (`ImportedParaHashes`) and
// the head itself (`ImportedParaHeads`. Pruning is not included here
db_weight.writes(2)
}

/// Returns weight of single parachain head pruning.
fn parachain_head_pruning_weight(db_weight: RuntimeDbWeight) -> Weight {
// it's just one write operation, we don't want any benchmarks for that
Expand Down

0 comments on commit 76be3f8

Please sign in to comment.