-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Conversation
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.
code looks good to me
frame/system/src/lib.rs
Outdated
@@ -1128,18 +1136,18 @@ impl<T: Config> Pallet<T> { | |||
|
|||
Pallet::<T>::on_killed_account(who.clone()); | |||
Ok(DecRefStatus::Reaped) | |||
}, |
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.
needs to run cargo fmt.
/// Currently this is triggered when: | ||
/// 1. Runtime code blob is changed or | ||
/// 2. `heap_pages` value is changed. | ||
RuntimeUpdated, |
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 personally wouldn't mind the more accurate name RuntimeOrHeapPagesUpdated
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.
RuntimeEnvironmentUpdated
frame/system/src/lib.rs
Outdated
@@ -1068,6 +1069,13 @@ impl<T: Config> Pallet<T> { | |||
Account::<T>::contains_key(who) | |||
} | |||
|
|||
fn do_set_code(code: Vec<u8>) -> DispatchResult { | |||
T::OnSetCode::set_code(code)?; | |||
Self::deposit_log(generic::DigestItem::RuntimeUpdated); |
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.
This will not work for Parachains.
Parachains have a special set_code
implementation that will not update :code
here directly. It will first queue the update and update it when it is allowed by the relay chain.
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.
Where can I find the queue implementation? Any chance the actual storage write can go through some function that would emit the log?
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.
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've exposed a helper function to update the storage and emit event + log. The idea is that this function will be used by parachain code implementation and is used by the default implementation of OnSetCode
for unit type.
frame/system/src/lib.rs
Outdated
@@ -298,7 +298,7 @@ pub mod pallet { | |||
|
|||
/// What to do if the user wants the code set to something. Just use `()` unless you are in | |||
/// cumulus. |
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 feel like doc here or doc for the SetCode
could mention about the log that needs to be deposited.
But it is hard to see where to tell about it.
bot merge |
Merge aborted: Checks failed for 6e99b76 |
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.
Sorry I am late to party, just discovered this PR.
@@ -184,6 +192,8 @@ pub enum DigestItemRef<'a, Hash: 'a> { | |||
ChangesTrieSignal(&'a ChangesTrieSignal), | |||
/// Any 'non-system' digest item, opaque to the native code. | |||
Other(&'a Vec<u8>), | |||
/// Runtime code or heap pages updated. | |||
RuntimeCodeOrHeapPagesUpdated, |
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.
Right now the story about heap pages is in flux. AFAIU, there is an interest to get rid of heap pages and or change the semantics at least.
In that case, maybe it would be better to split those digests in two: runtime code updated and heap pages updated? Then, if needed we deprecate the heap pages. The alternative would be to leave it as is and then change the semantics of RuntimeCodeOrHeapPagesUpdated
which seems a bit messier.
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 preferred RuntimeUpdated
, as it simply means "you might want to check whatever storage item concerns the runtime". The ambiguity is advantageous here.
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.
@thiolliere @bkchr are you guys okay to revert back to RuntimeUpdated
so that we can be a bit more flexible regarding what that actually means? My preference would be to have a single enum variant, especially if the heap pages one might get deprecated in the future.
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 also think that once we remove HeapPages stuff, RuntimeCodeOrHeapPagesUpdated always mean RuntimeCodeUpdated.
So the transition shouldn't be that messy. Anyway it is ok to me.
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.
Reverted back to RuntimeUpdated
.
quick question before this is merged, (not sure it is a good idea): should we check at substrate/client/db/src/lib.rs Line 2009 in 864d096 This way we ensure the digest is not added by the block builder without a storage update (same test could be added to cumulus). |
Do we do that for any other digest item? Note it's not an inherent (i.e. not block author's opinion), but rather a digest item and afair the only way to add them is through the runtime execution? That means that a block with an "extra" digest item would be considered invalid, because it wouldn't be generated by the runtime during |
I am not sure, but on a recent dropped branch I did manage some digest directly with the block builder after substrate/client/block-builder/src/lib.rs Line 226 in 864d096
Yet the check on block import would have need a cumulus implementation too. Edit: only did work because using substrate-test-runtime, using frame/executive, this wouldn't work. |
substrate/frame/executive/src/lib.rs Line 459 in 864d096
|
One short coming with this PR's design is that, in case of a fork at the block height that modifies the runtime, all forks will have that log item but a light client will not be able to know whether the forks did all update to the same runtime or to different ones. Including a hash of the code in the digest item would solve this, but would make the design more restrictive overall. I don't think it's a big deal to leave that unaddressed. |
That's actually something I wanted to add initially, but I don't think there is an efficient way to get the hash of the code without actually computing it on-chain. (i.e. no way to read storage item hash after write afaict). Also this complicates a bit the "heap pages" problem, since in such case the code hash stays the same. Unless we make the code hash optional or hash all of the runtime environment parameters (which might once again be a bit expensive). |
Shall we merge this? Is there any reason left to hold off this PR? |
None that I'm aware of. |
bot merge |
Trying merge. |
Late to the party: What about including the pre- and post-runtime version in the digest? |
I was considering including code hash in the digest (see here), but yeah the heap pages complicate that a bit - would probably be easier to have two separate digest items. |
Yeah, unfortunate that heap pages and code were lumped together. |
* Emit digest item on Runtime Code changes. * Add tests. * cargo +nightly fmt --all * Rename. * Add comment. * Move generic parameter to the trait. * cargo +nightly fmt --all * Elaborate in doc. * Revert to RuntimeUpdated name * cargo +nightly fmt --all * Rename to RuntimeEnvironmentUpdated
Related: #5047
Currently, we only emit an event in case the runtime code changes. However as described in #5047, for light clients it's difficult to track the code changes, cause reading events is not really feasible.
This PR introduces a
RuntimeUpdated
digest item, which is triggered on every code update (viaframe_system
dispatchables) or onheap_pages
change (also viaframe_system
function, not direct state write).This will allow the light clients to easily update the current code, based just on reading the digest items in the header.
Upgrade considerations
Since
DigestItem
is used in the client code as well (i.e. we decode the header digest), the nodes MUST be updated before rolling out the runtime upgrade.