Skip to content

Commit

Permalink
Use compact proofs for parachains (#2194)
Browse files Browse the repository at this point in the history
* Use compact proofs for parachains

* Remove StorageProofChecker

* Cleanup

Reuse messages proof generation from messages pallet (#2195)

* reuse messages proof generation from messages pallet

* incorrect merge

fixed remaining TODOs after messages pallet Config refactoring (#2196)

Return UntrustedVecDb from prove_storage() (#2197)

Storage proofs related renamings (#2198)

* Storage proofs related renamings

* Leftovers

* StorageSize -> StorageProofSize
  • Loading branch information
serban300 authored and bkontur committed Jun 5, 2024
1 parent 5e11510 commit 2fbdf04
Show file tree
Hide file tree
Showing 26 changed files with 603 additions and 828 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1121,7 +1121,7 @@ pub(crate) mod tests {
ParaId(BridgedUnderlyingParachain::PARACHAIN_ID),
[parachain_head_at_relay_header_number as u8; 32].into(),
)],
parachain_heads_proof: ParaHeadsProof { storage_proof: vec![] },
parachain_heads_proof: ParaHeadsProof { storage_proof: Default::default() },
})
}

Expand All @@ -1134,7 +1134,7 @@ pub(crate) mod tests {
ParaId(BridgedUnderlyingParachain::PARACHAIN_ID),
[parachain_head_at_relay_header_number as u8; 32].into(),
)],
parachain_heads_proof: ParaHeadsProof { storage_proof: vec![] },
parachain_heads_proof: ParaHeadsProof { storage_proof: Default::default() },
is_free_execution_expected: false,
})
}
Expand Down Expand Up @@ -2111,7 +2111,7 @@ pub(crate) mod tests {
[1u8; 32].into(),
),
],
parachain_heads_proof: ParaHeadsProof { storage_proof: vec![] },
parachain_heads_proof: ParaHeadsProof { storage_proof: Default::default() },
}),
message_delivery_call(200),
],
Expand Down
81 changes: 65 additions & 16 deletions bridges/bin/runtime-common/src/integrity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
//! Most of the tests in this module assume that the bridge is using standard (see `crate::messages`
//! module for details) configuration.

use bp_header_chain::ChainWithGrandpa;
use bp_messages::{ChainWithMessages, InboundLaneData, MessageNonce};
use bp_runtime::Chain;
use codec::Encode;
use frame_support::{storage::generator::StorageValue, traits::Get, weights::Weight};
use frame_system::limits;
Expand Down Expand Up @@ -54,19 +56,24 @@ macro_rules! assert_bridge_messages_pallet_types(
(
runtime: $r:path,
with_bridged_chain_messages_instance: $i:path,
this_chain: $this:path,
bridged_chain: $bridged:path,
) => {
{
// if one of asserts fail, then either bridge isn't configured properly (or alternatively - non-standard
// configuration is used), or something has broke existing configuration (meaning that all bridged chains
// and relays will stop functioning)
use $crate::messages_xcm_extension::XcmAsPlainPayload;
use bp_messages::ChainWithMessages;
use bp_runtime::Chain;
use pallet_bridge_messages::Config as MessagesConfig;
use static_assertions::assert_type_eq_all;

assert_type_eq_all!(<$r as MessagesConfig<$i>>::OutboundPayload, XcmAsPlainPayload);
assert_type_eq_all!(<$r as MessagesConfig<$i>>::ThisChain, $this);
assert_type_eq_all!(<$r as MessagesConfig<$i>>::BridgedChain, $bridged);

// TODO: https://github.com/paritytech/parity-bridges-common/issues/1666: check ThisChain, BridgedChain
// and BridgedHeaderChain types
assert_type_eq_all!(<$r as MessagesConfig<$i>>::OutboundPayload, XcmAsPlainPayload);
assert_type_eq_all!(<$r as MessagesConfig<$i>>::InboundPayload, XcmAsPlainPayload);
}
}
);
Expand All @@ -88,6 +95,8 @@ macro_rules! assert_complete_bridge_types(
$crate::assert_bridge_messages_pallet_types!(
runtime: $r,
with_bridged_chain_messages_instance: $mi,
this_chain: $this,
bridged_chain: $bridged,
);
}
);
Expand Down Expand Up @@ -161,14 +170,22 @@ where
"ActiveOutboundLanes ({:?}) must not be empty",
R::ActiveOutboundLanes::get(),
);

assert!(
pallet_bridge_messages::BridgedChainOf::<R, MI>::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX
<= pallet_bridge_messages::BridgedChainOf::<R, MI>::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX,
"MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX ({}) of {:?} is larger than \
its MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX ({}). This makes \
no sense",
pallet_bridge_messages::BridgedChainOf::<R, MI>::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX,
pallet_bridge_messages::BridgedChainOf::<R, MI>::ID,
pallet_bridge_messages::BridgedChainOf::<R, MI>::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX,
);
}

/// Parameters for asserting bridge pallet names.
#[derive(Debug)]
pub struct AssertBridgePalletNames<'a> {
/// Name of the messages pallet, deployed at the bridged chain and used to bridge with this
/// chain.
pub with_this_chain_messages_pallet_name: &'a str,
/// Name of the GRANDPA pallet, deployed at this chain and used to bridge with the bridged
/// chain.
pub with_bridged_chain_grandpa_pallet_name: &'a str,
Expand All @@ -179,16 +196,22 @@ pub struct AssertBridgePalletNames<'a> {

/// Tests that bridge pallet names used in `construct_runtime!()` macro call are matching constants
/// from chain primitives crates.
pub fn assert_bridge_pallet_names<R, GI, MI>(params: AssertBridgePalletNames)
fn assert_bridge_pallet_names<R, GI, MI>(params: AssertBridgePalletNames)
where
R: pallet_bridge_grandpa::Config<GI> + pallet_bridge_messages::Config<MI>,
GI: 'static,
MI: 'static,
{
// check that the bridge GRANDPA pallet has required name
assert_eq!(
pallet_bridge_grandpa::PalletOwner::<R, GI>::storage_value_final_key().to_vec(),
bp_runtime::storage_value_key(params.with_bridged_chain_grandpa_pallet_name, "PalletOwner",).0,
bp_runtime::storage_value_key(
params.with_bridged_chain_grandpa_pallet_name,
"PalletOwner",
).0,
);

// check that the bridge messages pallet has required name
assert_eq!(
pallet_bridge_messages::PalletOwner::<R, MI>::storage_value_final_key().to_vec(),
bp_runtime::storage_value_key(
Expand All @@ -201,27 +224,53 @@ where

/// Parameters for asserting complete standard messages bridge.
#[derive(Debug)]
pub struct AssertCompleteBridgeConstants<'a> {
pub struct AssertCompleteBridgeConstants {
/// Parameters to assert this chain constants.
pub this_chain_constants: AssertChainConstants,
/// Parameters to assert pallet names constants.
pub pallet_names: AssertBridgePalletNames<'a>,
}

/// All bridge-related constants tests for the complete standard messages bridge (i.e. with bridge
/// GRANDPA and messages pallets deployed).
pub fn assert_complete_bridge_constants<R, GI, MI>(params: AssertCompleteBridgeConstants)
where
/// All bridge-related constants tests for the complete standard relay-chain messages bridge
/// (i.e. with bridge GRANDPA and messages pallets deployed).
pub fn assert_complete_with_relay_chain_bridge_constants<R, GI, MI>(
params: AssertCompleteBridgeConstants,
) where
R: frame_system::Config
+ pallet_bridge_grandpa::Config<GI>
+ pallet_bridge_messages::Config<MI>,
GI: 'static,
MI: 'static,
{
assert_chain_constants::<R>(params.this_chain_constants);
assert_bridge_grandpa_pallet_constants::<R, GI>();
assert_bridge_messages_pallet_constants::<R, MI>();
assert_bridge_pallet_names::<R, GI, MI>(AssertBridgePalletNames {
with_bridged_chain_grandpa_pallet_name:
<R as pallet_bridge_grandpa::Config<GI>>::BridgedChain::WITH_CHAIN_GRANDPA_PALLET_NAME,
with_bridged_chain_messages_pallet_name:
<R as pallet_bridge_messages::Config<MI>>::BridgedChain::WITH_CHAIN_MESSAGES_PALLET_NAME,
});
}

/// All bridge-related constants tests for the complete standard parachain messages bridge
/// (i.e. with bridge GRANDPA, parachains and messages pallets deployed).
pub fn assert_complete_with_parachain_bridge_constants<R, GI, MI, RelayChain>(
params: AssertCompleteBridgeConstants,
) where
R: frame_system::Config
+ pallet_bridge_grandpa::Config<GI>
+ pallet_bridge_messages::Config<MI>,
GI: 'static,
MI: 'static,
RelayChain: ChainWithGrandpa,
{
assert_chain_constants::<R>(params.this_chain_constants);
assert_bridge_grandpa_pallet_constants::<R, GI>();
assert_bridge_messages_pallet_constants::<R, MI>();
assert_bridge_pallet_names::<R, GI, MI>(params.pallet_names);
assert_bridge_pallet_names::<R, GI, MI>(AssertBridgePalletNames {
with_bridged_chain_grandpa_pallet_name: RelayChain::WITH_CHAIN_GRANDPA_PALLET_NAME,
with_bridged_chain_messages_pallet_name:
<R as pallet_bridge_messages::Config<MI>>::BridgedChain::WITH_CHAIN_MESSAGES_PALLET_NAME,
});
}

/// Check that the message lane weights are correct.
Expand Down
103 changes: 14 additions & 89 deletions bridges/bin/runtime-common/src/messages_benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,42 +19,24 @@

#![cfg(feature = "runtime-benchmarks")]

// use crate::{
// messages::{BridgedChain, HashOf, ThisChain},
// messages_generation::{
// encode_all_messages, encode_lane_data, prepare_message_delivery_storage_proof,
// prepare_messages_storage_proof,
// },
// };

use bp_messages::{
source_chain::FromBridgedChainMessagesDeliveryProof,
target_chain::FromBridgedChainMessagesProof, MessagePayload,
};
use bp_polkadot_core::parachains::ParaHash;
use bp_runtime::{Chain, Parachain, StorageProofSize};
// TODO: https://github.com/paritytech/parity-bridges-common/issues/1666 - merge with message
// generation methods from messages pallet and use it here

use bp_messages::{storage_keys, ChainWithMessages};
use bp_runtime::{
grow_trie_leaf_value, record_all_trie_keys, AccountIdOf, HashOf, HasherOf, UntrustedVecDb,
};
use bp_runtime::{AccountIdOf, Chain, HashOf, Parachain, StorageProofSize};
use codec::Encode;
use frame_support::weights::Weight;
use pallet_bridge_messages::{
benchmarking::{MessageDeliveryProofParams, MessageProofParams},
messages_generation::{encode_all_messages, encode_lane_data, prepare_messages_storage_proof},
messages_generation::{
encode_all_messages, encode_lane_data, prepare_message_delivery_storage_proof,
prepare_messages_storage_proof,
},
BridgedChainOf, ThisChainOf,
};
use sp_runtime::{
traits::{Header, Zero},
StateVersion,
};
use sp_runtime::traits::{Header, Zero};
use sp_std::prelude::*;
use sp_trie::{
LayoutV0, LayoutV1, MemoryDB, StorageProof, TrieConfiguration, TrieDBMutBuilder, TrieMut,
};
use xcm::latest::prelude::*;

/// Prepare inbound bridge message according to given message proof parameters.
Expand Down Expand Up @@ -201,7 +183,10 @@ where
{
// prepare storage proof
let lane = params.lane;
let (state_root, storage_proof) = prepare_message_delivery_proof::<R, MI>(params);
let (state_root, storage_proof) = prepare_message_delivery_storage_proof::<
BridgedChainOf<R, MI>,
ThisChainOf<R, MI>,
>(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 @@ -229,7 +214,10 @@ where
{
// prepare storage proof
let lane = params.lane;
let (state_root, storage_proof) = prepare_message_delivery_proof::<R, MI>(params);
let (state_root, storage_proof) = prepare_message_delivery_storage_proof::<
BridgedChainOf<R, MI>,
ThisChainOf<R, MI>,
>(params.lane, params.inbound_lane_data, params.size);

// update runtime storage
let (_, bridged_header_hash) =
Expand All @@ -242,69 +230,6 @@ where
}
}

/// Prepare in-memory message delivery proof, without inserting anything to the runtime storage.
fn prepare_message_delivery_proof<R, MI>(
params: MessageDeliveryProofParams<AccountIdOf<ThisChainOf<R, MI>>>,
) -> (HashOf<BridgedChainOf<R, MI>>, UntrustedVecDb)
where
R: pallet_bridge_messages::Config<MI>,
MI: 'static,
{
match BridgedChainOf::<R, MI>::STATE_VERSION {
StateVersion::V0 =>
do_prepare_message_delivery_proof::<R, MI, LayoutV0<HasherOf<BridgedChainOf<R, MI>>>>(
params,
),
StateVersion::V1 =>
do_prepare_message_delivery_proof::<R, MI, LayoutV1<HasherOf<BridgedChainOf<R, MI>>>>(
params,
),
}
}

/// Prepare in-memory message delivery proof, without inserting anything to the runtime storage.
fn do_prepare_message_delivery_proof<
R,
MI,
L: TrieConfiguration<Hash = HasherOf<BridgedChainOf<R, MI>>>,
>(
params: MessageDeliveryProofParams<AccountIdOf<ThisChainOf<R, MI>>>,
) -> (HashOf<BridgedChainOf<R, MI>>, UntrustedVecDb)
where
R: pallet_bridge_messages::Config<MI>,
MI: 'static,
{
// prepare Bridged chain storage with inbound lane state
let storage_key = storage_keys::inbound_lane_data_key(
R::ThisChain::WITH_CHAIN_MESSAGES_PALLET_NAME,
&params.lane,
)
.0;
let mut root = Default::default();
let mut mdb = MemoryDB::default();
{
let mut trie = TrieDBMutBuilder::<L>::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 read_proof = record_all_trie_keys::<L, _>(&mdb, &root)
.map_err(|_| "record_all_trie_keys has failed")
.expect("record_all_trie_keys should not fail in benchmarks");
let storage_proof = UntrustedVecDb::try_new::<HasherOf<BridgedChainOf<R, MI>>>(
StorageProof::new(read_proof),
root,
vec![storage_key],
)
.unwrap();

(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
Loading

0 comments on commit 2fbdf04

Please sign in to comment.