-
Notifications
You must be signed in to change notification settings - Fork 709
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PoV Reclaim Runtime Side #3002
PoV Reclaim Runtime Side #3002
Changes from all commits
9bacb18
fca700f
fd3b613
f808645
088dd8d
ce33ece
0468623
72b8818
ec26a45
fb86674
00dbfb6
102c17e
903a026
d9550e3
a54f670
93c5570
a257a52
9433f16
2f8244e
0f44605
b308598
872f170
5386108
6af533b
fb523e5
03074da
f6bb796
eb79558
b8012be
2a5cfba
fdfa266
408f7c7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,7 +16,7 @@ | |
|
||
//! The actual implementation of the validate block functionality. | ||
|
||
use super::{trie_cache, MemoryOptimizedValidationParams}; | ||
use super::{trie_cache, trie_recorder, MemoryOptimizedValidationParams}; | ||
use cumulus_primitives_core::{ | ||
relay_chain::Hash as RHash, ParachainBlockData, PersistedValidationData, | ||
}; | ||
|
@@ -34,12 +34,14 @@ use sp_externalities::{set_and_run_with_externalities, Externalities}; | |
use sp_io::KillStorageResult; | ||
use sp_runtime::traits::{Block as BlockT, Extrinsic, HashingFor, Header as HeaderT}; | ||
use sp_std::prelude::*; | ||
use sp_trie::MemoryDB; | ||
use sp_trie::{MemoryDB, ProofSizeProvider}; | ||
use trie_recorder::SizeOnlyRecorderProvider; | ||
|
||
type TrieBackend<B> = sp_state_machine::TrieBackend< | ||
MemoryDB<HashingFor<B>>, | ||
HashingFor<B>, | ||
trie_cache::CacheProvider<HashingFor<B>>, | ||
SizeOnlyRecorderProvider<HashingFor<B>>, | ||
>; | ||
|
||
type Ext<'a, B> = sp_state_machine::Ext<'a, HashingFor<B>, TrieBackend<B>>; | ||
|
@@ -48,6 +50,9 @@ fn with_externalities<F: FnOnce(&mut dyn Externalities) -> R, R>(f: F) -> R { | |
sp_externalities::with_externalities(f).expect("Environmental externalities not set.") | ||
} | ||
|
||
// Recorder instance to be used during this validate_block call. | ||
environmental::environmental!(recorder: trait ProofSizeProvider); | ||
|
||
/// Validate the given parachain block. | ||
/// | ||
/// This function is doing roughly the following: | ||
|
@@ -120,6 +125,7 @@ where | |
|
||
sp_std::mem::drop(storage_proof); | ||
|
||
let mut recorder = SizeOnlyRecorderProvider::new(); | ||
let cache_provider = trie_cache::CacheProvider::new(); | ||
// We use the storage root of the `parent_head` to ensure that it is the correct root. | ||
// This is already being done above while creating the in-memory db, but let's be paranoid!! | ||
|
@@ -128,6 +134,7 @@ where | |
*parent_header.state_root(), | ||
cache_provider, | ||
) | ||
.with_recorder(recorder.clone()) | ||
.build(); | ||
|
||
let _guard = ( | ||
|
@@ -167,9 +174,11 @@ where | |
.replace_implementation(host_default_child_storage_next_key), | ||
sp_io::offchain_index::host_set.replace_implementation(host_offchain_index_set), | ||
sp_io::offchain_index::host_clear.replace_implementation(host_offchain_index_clear), | ||
cumulus_primitives_proof_size_hostfunction::storage_proof_size::host_storage_proof_size | ||
.replace_implementation(host_storage_proof_size), | ||
); | ||
|
||
run_with_externalities::<B, _, _>(&backend, || { | ||
run_with_externalities_and_recorder::<B, _, _>(&backend, &mut recorder, || { | ||
let relay_chain_proof = crate::RelayChainStateProof::new( | ||
PSC::SelfParaId::get(), | ||
inherent_data.validation_data.relay_parent_storage_root, | ||
|
@@ -190,7 +199,7 @@ where | |
} | ||
}); | ||
|
||
run_with_externalities::<B, _, _>(&backend, || { | ||
run_with_externalities_and_recorder::<B, _, _>(&backend, &mut recorder, || { | ||
let head_data = HeadData(block.header().encode()); | ||
|
||
E::execute_block(block); | ||
|
@@ -265,15 +274,17 @@ fn validate_validation_data( | |
); | ||
} | ||
|
||
/// Run the given closure with the externalities set. | ||
fn run_with_externalities<B: BlockT, R, F: FnOnce() -> R>( | ||
/// Run the given closure with the externalities and recorder set. | ||
fn run_with_externalities_and_recorder<B: BlockT, R, F: FnOnce() -> R>( | ||
backend: &TrieBackend<B>, | ||
recorder: &mut SizeOnlyRecorderProvider<HashingFor<B>>, | ||
execute: F, | ||
) -> R { | ||
let mut overlay = sp_state_machine::OverlayedChanges::default(); | ||
let mut ext = Ext::<B>::new(&mut overlay, backend); | ||
recorder.reset(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually realizing that my comment last time was not correct 🙈 Given that we reset the |
||
|
||
set_and_run_with_externalities(&mut ext, || execute()) | ||
recorder::using(recorder, || set_and_run_with_externalities(&mut ext, || execute())) | ||
} | ||
|
||
fn host_storage_read(key: &[u8], value_out: &mut [u8], value_offset: u32) -> Option<u32> { | ||
|
@@ -305,6 +316,10 @@ fn host_storage_clear(key: &[u8]) { | |
with_externalities(|ext| ext.place_storage(key.to_vec(), None)) | ||
} | ||
|
||
fn host_storage_proof_size() -> u64 { | ||
recorder::with(|rec| rec.estimate_encoded_size()).expect("Recorder is always set; qed") as _ | ||
} | ||
|
||
fn host_storage_root(version: StateVersion) -> Vec<u8> { | ||
with_externalities(|ext| ext.storage_root(version)) | ||
} | ||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -40,7 +40,10 @@ use substrate_prometheus_endpoint::Registry; | |||||||||||||||||
pub struct ParachainNativeExecutor; | ||||||||||||||||||
|
||||||||||||||||||
impl sc_executor::NativeExecutionDispatch for ParachainNativeExecutor { | ||||||||||||||||||
type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions; | ||||||||||||||||||
type ExtendHostFunctions = ( | ||||||||||||||||||
cumulus_client_service::storage_proof_size::HostFunctions, | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we propose this host function in the template. Maybe we should also need to add the Otherwise what is its usage? IIUC the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The polkadot-sdk/substrate/frame/executive/src/lib.rs Lines 607 to 614 in 150a360
This means that the weightreclaimer should only modify the value in the weightmeter, not the storage value itself.
This is a good point, I will add it. |
||||||||||||||||||
frame_benchmarking::benchmarking::HostFunctions, | ||||||||||||||||||
); | ||||||||||||||||||
|
||||||||||||||||||
fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> { | ||||||||||||||||||
parachain_template_runtime::api::dispatch(method, data) | ||||||||||||||||||
|
@@ -100,10 +103,11 @@ pub fn new_partial(config: &Configuration) -> Result<Service, sc_service::Error> | |||||||||||||||||
let executor = ParachainExecutor::new_with_wasm_executor(wasm); | ||||||||||||||||||
|
||||||||||||||||||
let (client, backend, keystore_container, task_manager) = | ||||||||||||||||||
sc_service::new_full_parts::<Block, RuntimeApi, _>( | ||||||||||||||||||
sc_service::new_full_parts_record_import::<Block, RuntimeApi, _>( | ||||||||||||||||||
config, | ||||||||||||||||||
telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()), | ||||||||||||||||||
executor, | ||||||||||||||||||
true, | ||||||||||||||||||
)?; | ||||||||||||||||||
let client = Arc::new(client); | ||||||||||||||||||
|
||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dumb question: do we need access to the recorder in this closure as well?
Shouldn't we need access to the recorder only in the scope where we call
execute_block
only?(i.e. in the call below)
Or we need it to
check_inherents
as well?Another dumb question: why we need two calls to
run_with_externalities_and_recorder
?Can't we unify the closures in a single one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, we should not need it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let me phrase it better, we should NOT use the recorder.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean we need to supply the recorder everywhere where host functions are potentially being called. And since the
CheckInherent
type is user supplied, host functions could be called there.The two closures are separate because we want to start with a fresh overlay and externalities. But this is a good point, I now reset the recorder too between these two code sections.