Skip to content
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

Merged
merged 9 commits into from
Aug 10, 2023

Conversation

tadeohepperle
Copy link
Contributor

@tadeohepperle tadeohepperle commented Aug 7, 2023

This PR adds two methods storage_version(pallet_name) and runtime_wasm_code to the storage to fetch the respective data from the node. I also wanted to add other keys (see mod well_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.

@tadeohepperle tadeohepperle changed the title Add storage_version() to storage Add storage_version() and runtime_wasm_code() storage Aug 8, 2023
@tadeohepperle tadeohepperle changed the title Add storage_version() and runtime_wasm_code() storage Add storage_version() and runtime_wasm_code() to storage Aug 8, 2023
@tadeohepperle tadeohepperle marked this pull request as ready for review August 8, 2023 08:47
@tadeohepperle tadeohepperle requested a review from a team as a code owner August 8, 2023 08:47
));

// fetch the raw bytes and decode them into the StorageVersion struct:
let storage_version_bytes = self.fetch_raw(&key_bytes).await?.ok_or(format!(
Copy link
Collaborator

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)

@@ -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 {
Copy link
Collaborator

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!).

Copy link
Contributor Author

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.

Copy link
Collaborator

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!

Copy link
Collaborator

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

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree!

@@ -237,6 +241,43 @@ where
})
}
}

/// the storage version of a pallet.
Copy link
Collaborator

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")
Copy link
Collaborator

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.

Copy link
Contributor Author

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?

Copy link
Collaborator

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?)

Comment on lines 278 to 281
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;")
))?;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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;")
))?;

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;")
Copy link
Collaborator

@jsdw jsdw Aug 9, 2023

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",

scale_encode::EncodeAsType,
scale_decode::DecodeAsType,
)]
pub struct StorageVersion(u16);
Copy link
Collaborator

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:

  1. Make the u16 pub (that's probably what they care about but currently it's inaccessible, or
  2. Just return a u16 from storage_version (that's my preference; I don't think this struct adds anything)

Copy link
Collaborator

@jsdw jsdw left a 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:
Copy link
Collaborator

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?

@tadeohepperle tadeohepperle merged commit 9723a50 into master Aug 10, 2023
8 checks passed
@tadeohepperle tadeohepperle deleted the tadeo-hepperle-add-pallet-version-storage-api branch August 10, 2023 13:40
@jsdw jsdw mentioned this pull request Sep 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants