-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Do not call initialize_block
before any runtime api
#8953
Conversation
Before this change we always called `initialize_block` before calling into the runtime. There was already support with `skip_initialize` to skip the initialization. Almost no runtime_api requires that `initialize_block` is called before. Actually this only leads to higher execution times most of the time, because all runtime modules are initialized and this is especially expensive when the block contained a runtime upgrade. TLDR: Do not call `initialize_block` before calling a runtime api.
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.
Looks good, but I'm surprised there is no docs being updated. I think it's worth to document the behavior now.
client/light/src/call_executor.rs
Outdated
/// Proof should include both environment preparation proof and method execution proof. | ||
pub fn check_execution_proof_with_make_header<Header, E, H, MakeNextHeader>( | ||
pub fn check_execution_proof_with_make_header<Header, E, H>( |
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.
The method name doesn't make sense now?
client/light/src/call_executor.rs
Outdated
@@ -230,62 +211,41 @@ pub fn check_execution_proof<Header, E, H>( | |||
H: Hasher, | |||
H::Out: Ord + codec::Codec + 'static, | |||
{ | |||
check_execution_proof_with_make_header::<Header, E, H, _>( | |||
check_execution_proof_with_make_header::<Header, E, H>( |
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.
Doesn't this break compatibility between proof formats? Are there no consequences?
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.
Awesome work!
/// Validate the transaction. | ||
/// | ||
/// This method is invoked by the transaction pool to learn details about given transaction. | ||
/// The implementation should make sure to verify the correctness of the transaction | ||
/// against current state. | ||
/// against current state. The given `block_hash` corresponds to the hash of the block | ||
/// that is used as current state. |
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.
Shall we add info about the need to manually initialize the frame_system
pallet?
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.
For frame this is done automatically through Executive::validate_transaction
. While this is also just required when you have a signed extension that checks for block hashes.
@@ -198,6 +198,11 @@ impl RuntimeVersion { | |||
) -> bool { | |||
self.apis.iter().any(|(s, v)| s == id && predicate(*v)) | |||
} | |||
|
|||
/// Returns the api version found for api with `id`. | |||
pub fn api_version(&self, id: &ApiId) -> Option<u32> { |
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.
🙏
Prior this patch, when an runtime API is called we would call Specifically, a difference in behavior will be observed if an runtime API accesses some state that can be changed either in I went through all the runtime API impls and have marked some that do that. Getting into the list doesn't mean that they are wrong, but I think it would be a good idea to check for somebody deeply familiar with the respective code, or at least acknowledge that they are aware of this change. Here is the list:
|
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.
Regarding the patch itself, LGTM!
Thanks @pepyakin! |
I checked again Babe and AuthorityDiscovery and couldn't find anything problematic. |
bot merge |
Trying merge. |
Both BABE and GRANDPA should be unaffected, I wasn't sure about the equivocation report submission but I tested it now. |
* Do not call `initialize_block` before any runtime api Before this change we always called `initialize_block` before calling into the runtime. There was already support with `skip_initialize` to skip the initialization. Almost no runtime_api requires that `initialize_block` is called before. Actually this only leads to higher execution times most of the time, because all runtime modules are initialized and this is especially expensive when the block contained a runtime upgrade. TLDR: Do not call `initialize_block` before calling a runtime api. * Change `validate_transaction` interface * Fix rpc test * Fixes and comments * Some docs
What is the recommended way to port runtime APIs that actually did depend on the initialization? Should each one manually initialize only what it needs to? cc @tgmichel I believe this is the change that broke our EVM tracing. |
@JoshOrndorff not super familiar with how one might initialize the block, but it may be that rather than trying to turn this back on, you actually want to see if you can adjust your code or tracing to work without needing this initialize. I think in general, it is risky to your chain's performance if you have any of the runtime apis call (afaik, not an expert on this) |
Yeah, I would not advise to do this. If possible, I would prevent this. Or if you only need to initialize some stuff like |
@shawntabrizi Thanks for the feedback. |
* Do not call `initialize_block` before any runtime api Before this change we always called `initialize_block` before calling into the runtime. There was already support with `skip_initialize` to skip the initialization. Almost no runtime_api requires that `initialize_block` is called before. Actually this only leads to higher execution times most of the time, because all runtime modules are initialized and this is especially expensive when the block contained a runtime upgrade. TLDR: Do not call `initialize_block` before calling a runtime api. * Change `validate_transaction` interface * Fix rpc test * Fixes and comments * Some docs
Before this PR was merged, was each pallet's |
Yes |
* Do not call `initialize_block` before any runtime api Before this change we always called `initialize_block` before calling into the runtime. There was already support with `skip_initialize` to skip the initialization. Almost no runtime_api requires that `initialize_block` is called before. Actually this only leads to higher execution times most of the time, because all runtime modules are initialized and this is especially expensive when the block contained a runtime upgrade. TLDR: Do not call `initialize_block` before calling a runtime api. * Change `validate_transaction` interface * Fix rpc test * Fixes and comments * Some docs Signed-off-by: Vladislav Markushin <negigic@gmail.com>
Before this change we always called
initialize_block
before callinginto the runtime. There was already support with
skip_initialize
to skipthe initialization. Almost no runtime_api requires that
initialize_block
is called before. Actually this only leads to higherexecution times most of the time, because all runtime modules are
initialized and this is especially expensive when the block contained a
runtime upgrade.
TLDR: Do not call
initialize_block
before calling a runtime api.Fixes: paritytech/polkadot#3053
polkadot companion: paritytech/polkadot#3140