-
Notifications
You must be signed in to change notification settings - Fork 248
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
Add storage_version()
and runtime_wasm_code()
to storage
#1111
Add storage_version()
and runtime_wasm_code()
to storage
#1111
Conversation
storage_version()
and runtime_wasm_code()
storage
storage_version()
and runtime_wasm_code()
storagestorage_version()
and runtime_wasm_code()
to storage
subxt/src/storage/storage_type.rs
Outdated
)); | ||
|
||
// fetch the raw bytes and decode them into the StorageVersion struct: | ||
let storage_version_bytes = self.fetch_raw(&key_bytes).await?.ok_or(format!( |
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.
Nit: ok_or_else
here toa void formatting the string unless there's an error (I'd expect clippy to spot this but havent checked)
subxt/src/storage/utils.rs
Outdated
@@ -37,3 +37,50 @@ pub(crate) fn storage_address_root_bytes<Address: StorageAddress>(addr: &Address | |||
write_storage_address_root_bytes(addr, &mut bytes); | |||
bytes | |||
} | |||
|
|||
/// this should match the constants in the module `sp_core::storage::well_known_keys` | |||
pub mod well_known_keys { |
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'd probably keep this in subxt::storage
and not utils (it's storage specific I think?).
Is there a use in exposing any of this stuff at all? I'd be inclined to just inline what you need into the runtime_wasm_code
function for now, with a pointer to where you got the key from there so we can add more if need be or whatever.
Alternately we could expose this WellKnownKey<R>
type in subxt::storage
and then a single api.storage().fetch_well_known_key(key: WellKnownKey<R>) -> Result<R, Error>
type function to fetch them (it sortof depends whether any of the other keys are actually useful anywhere; that might be worth finding out!).
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 is in subxt::storage::utils
not in the general subxt::utils
. I wanted to expose a "nicer" interface in the hopes that many other well known keys might work in a similar fashion, such that we can abstract over their types and keys with a function like fetch_well_known_key()
on the storage.
But the other keys do not seem to work as intended and I think you are right, it is less bloat to just hardcode the ":code"
in the right place and remove the other stuff here. Also first I thought the returned value was scale decoded but that is also not the case apparently.
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.
Ok that makes sense to me; let's keep it simple then until we see a use for allowing other keys!
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.
It would be interesting to investigate what is causing the failure in Polkadot for the other known keys :D
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 agree!
subxt/src/storage/storage_type.rs
Outdated
@@ -237,6 +241,43 @@ where | |||
}) | |||
} | |||
} | |||
|
|||
/// the storage version of a 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.
nit: I prefer upper case for documentation and for consistency, but totally up to you
.storage() | ||
.at_latest() | ||
.await? | ||
.storage_version("System") |
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.
Crazy thought here; could we use this to do a quick version validation? Similar to our hashing, I guess that would require substrate to constantly modify these numbers appropriately with changes.
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.
When would that version validation happen? I guess we would need to make about 30 concurrent calls to validate all pallets. Or we might just validate the pallet whenever a storage query/call is made for a specific 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.
We already validate the keys and value types on a per-entry basis so probably what we have is already better (I imagine the version might increment for every storage change, but not really sure what it represents exactly?)
subxt/src/storage/storage_type.rs
Outdated
let data = self.fetch_raw(CODE).await?.ok_or(format!( | ||
"Unexpected: entry for well known key \"{}\" not found", | ||
std::str::from_utf8(CODE).expect("qed;") | ||
))?; |
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 data = self.fetch_raw(CODE).await?.ok_or(format!( | |
"Unexpected: entry for well known key \"{}\" not found", | |
std::str::from_utf8(CODE).expect("qed;") | |
))?; | |
let data = self.fetch_raw(CODE).await?.ok_or_else(|| format!( | |
"Unexpected: entry for well known key \"{}\" not found", | |
std::str::from_utf8(CODE).expect("qed;") | |
))?; |
subxt/src/storage/storage_type.rs
Outdated
const CODE: &[u8] = b":code"; | ||
let data = self.fetch_raw(CODE).await?.ok_or(format!( | ||
"Unexpected: entry for well known key \"{}\" not found", | ||
std::str::from_utf8(CODE).expect("qed;") |
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.
If you wanted to simplify this you could just have:
const CODE: &str = ":code";
let data = self.fetch_raw(CODE.as_bytes()).await?.ok_or_else(|| format!(
"Unexpected: entry for well known key \"{CODE}\" not found",
subxt/src/utils/mod.rs
Outdated
scale_encode::EncodeAsType, | ||
scale_decode::DecodeAsType, | ||
)] | ||
pub struct StorageVersion(u16); |
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.
Since we return this to the user we should either:
- Make the
u16
pub (that's probably what they care about but currently it's inaccessible, or - Just return a
u16
fromstorage_version
(that's my preference; I don't think this struct adds anything)
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 looks good to me now; nice one :)
STORAGE_VERSION_STORAGE_KEY_POSTFIX, | ||
)); | ||
|
||
// fetch the raw bytes and decode them into the StorageVersion struct: |
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.
nit: Does this comment needs updating?
This PR adds two methods
storage_version(pallet_name)
andruntime_wasm_code
to the storage to fetch the respective data from the node. I also wanted to add other keys (see modwell_known_keys
) but retrieving data with them did not work (at least with the polakdot node I tried it with). I left them in the PR as private to maybe activate them in the future if necessary.