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

TryDecodeEntireState check for storage types and pallets #1805

Merged
merged 31 commits into from
Nov 6, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
292b747
patch outcome
PieWol Oct 5, 2023
5ebb6db
remove patchfile
PieWol Oct 6, 2023
5d20d23
Merge branch 'paritytech:master' into decode-all
PieWol Oct 6, 2023
c6128fa
Merge branch 'master' into decode-all
ggwpez Oct 21, 2023
ee5b1df
Make stuff compile
ggwpez Oct 21, 2023
720ebb2
Introduce custom error type
ggwpez Oct 21, 2023
993c2c7
Move stuff into own files
ggwpez Oct 21, 2023
61883ba
Cleanup
ggwpez Oct 21, 2023
1cf9ae2
Add prdoc
ggwpez Oct 21, 2023
7e4394d
Update UI tests
ggwpez Oct 21, 2023
30569ac
Add to Rococo and Westend runtimes
ggwpez Oct 21, 2023
30bb3b1
Add log
ggwpez Oct 21, 2023
e2e22e3
fmt
ggwpez Oct 21, 2023
25741db
Remove migration struct and call directly from executive
ggwpez Oct 24, 2023
4890794
Fix
ggwpez Oct 24, 2023
1c34c2d
Nicer error print
ggwpez Oct 24, 2023
b4851d4
Merge remote-tracking branch 'origin/master' into decode-all
ggwpez Oct 24, 2023
b003d2e
Fix debug print
ggwpez Oct 24, 2023
3c9907a
Fix docs
ggwpez Oct 24, 2023
e00cab5
Merge branch 'master' into decode-all
ggwpez Oct 24, 2023
ba1a5bb
Merge branch 'master' into decode-all
ggwpez Oct 24, 2023
022e1e7
Apply suggestions from code review
ggwpez Oct 26, 2023
4623145
Return all errors
ggwpez Oct 26, 2023
d7688b2
Also try to decode the state in try_execute_block
ggwpez Oct 26, 2023
fbb1e25
Tweak error print
ggwpez Oct 26, 2023
81885ff
Fix CI
ggwpez Oct 26, 2023
2d8b214
log extended info to debug
ggwpez Oct 27, 2023
5472c3e
Prefix runtime log target
ggwpez Nov 6, 2023
41056ab
Merge remote-tracking branch 'origin/master' into decode-all
ggwpez Nov 6, 2023
3119539
Resolve unused import
ggwpez Nov 6, 2023
ac80d5d
Merge branch 'master' into decode-all
ggwpez Nov 6, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -849,11 +849,11 @@ pub fn expand_storages(def: &mut Def) -> proc_macro2::TokenStream {
impl<#type_impl_gen> #frame_support::traits::TryDecodeEntireStorage
for #pallet_ident<#type_use_gen> #completed_where_clause
{
fn try_decode_entire_state() -> Result<usize, &'static str> {
fn try_decode_entire_state() -> Result<usize, #frame_support::traits::TryDecodeEntireStorageError> {
// simply delegate impl to a tuple of all storage items we have.
//
// NOTE: for now, we have to exclude storage items that are feature gated.
<( #( #storage_names ),*) as frame_support::traits::TryDecodeEntireStorage>::try_decode_entire_state()
<( #( #storage_names ),*) as #frame_support::traits::TryDecodeEntireStorage>::try_decode_entire_state()
}
}
)
Expand Down
14 changes: 13 additions & 1 deletion substrate/frame/support/src/storage/migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -408,12 +408,24 @@ impl<AllPallets: crate::traits::TryDecodeEntireStorage> crate::traits::OnRuntime
}

fn post_upgrade(_: Vec<u8>) -> Result<(), sp_runtime::TryRuntimeError> {
let decoded = AllPallets::try_decode_entire_state()?;
let decoded = match AllPallets::try_decode_entire_state() {
Ok(bytes) => bytes,
Err(err) => {
log::info!(
target: crate::LOG_TARGET,
"failed to decode the entire state: {}", err
);
// NOTE: This only supports static strings.
return Err("failed to decode a value from the storage".into())
}
};

log::info!(
target: crate::LOG_TARGET,
"decoded the entire state, total size = {} bytes",
decoded
);

Ok(())
}
}
Expand Down
2 changes: 1 addition & 1 deletion substrate/frame/support/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,5 +126,5 @@ pub use tx_pause::{TransactionPause, TransactionPauseError};
mod try_runtime;
#[cfg(feature = "try-runtime")]
pub use try_runtime::{
Select as TryStateSelect, TryDecodeEntireStorage, TryState, UpgradeCheckSelect,
Select as TryStateSelect, TryDecodeEntireStorageError, TryDecodeEntireStorage, TryState, UpgradeCheckSelect,
};
43 changes: 32 additions & 11 deletions substrate/frame/support/src/traits/try_runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,26 +63,47 @@ impl Default for Select {
/// decoded bytes if `Ok(_)`.
pub trait TryDecodeEntireStorage {
/// Decode the entire data under the given storage, returning `Ok(bytes_decoded)` if success.
fn try_decode_entire_state() -> Result<usize, &'static str>;
fn try_decode_entire_state() -> Result<usize, TryDecodeEntireStorageError>;
}

#[cfg_attr(all(not(feature = "tuples-96"), not(feature = "tuples-128")), impl_for_tuples(64))]
#[cfg_attr(all(feature = "tuples-96", not(feature = "tuples-128")), impl_for_tuples(96))]
#[cfg_attr(feature = "tuples-128", impl_for_tuples(128))]
impl TryDecodeEntireStorage for Tuple {
fn try_decode_entire_state() -> Result<usize, &'static str> {
fn try_decode_entire_state() -> Result<usize, TryDecodeEntireStorageError> {
let mut len = 0usize;
for_tuples!( #( len = len.saturating_add(Tuple::try_decode_entire_state()?); )* );
Ok(len)
}
}

/// A value could not be decoded.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TryDecodeEntireStorageError {
/// The key of the undecodable value.
key: Vec<u8>,
/// The raw value.
raw: Option<Vec<u8>>,
/// The storage info of the key.
info: StorageInfo,
ggwpez marked this conversation as resolved.
Show resolved Hide resolved
}

impl core::fmt::Display for TryDecodeEntireStorageError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(
f,
"Failed to decode value at key {:?} with storage info {:?}. Raw value: {:?}",
self.key, self.info, self.raw,
)
}
}

/// Decode all the values based on the prefix of `info` to `V`.
///
/// Basically, it decodes and sums up all the values who's key start with `info.prefix`. For values,
/// this would be the value itself. For all sorts of maps, this should be all map items in the
/// absence of key collision.
fn decode_storage_info<V: Decode>(info: StorageInfo) -> Result<usize, &'static str> {
fn decode_storage_info<V: Decode>(info: StorageInfo) -> Result<usize, TryDecodeEntireStorageError> {
let mut next_key = info.prefix.clone();
let mut decoded = 0;

Expand All @@ -92,9 +113,9 @@ fn decode_storage_info<V: Decode>(info: StorageInfo) -> Result<usize, &'static s
let len = bytes.len();
let _ = <V as DecodeAll>::decode_all(&mut bytes.as_ref()).map_err(|_| {
log::error!(target: crate::LOG_TARGET, "failed to decoded {:?}", info,);
"failed to decode value under existing key"
TryDecodeEntireStorageError { key: key.to_vec(), raw: Some(bytes.to_vec()), info: info.clone() }
})?;
Ok::<usize, &'static str>(len)
Ok::<usize, TryDecodeEntireStorageError>(len)
},
};

Expand All @@ -120,7 +141,7 @@ where
QueryKind: QueryKindTrait<Value, OnEmpty>,
OnEmpty: Get<QueryKind::Query> + 'static,
{
fn try_decode_entire_state() -> Result<usize, &'static str> {
fn try_decode_entire_state() -> Result<usize, TryDecodeEntireStorageError> {
let info = Self::partial_storage_info()
.first()
.cloned()
Expand All @@ -140,7 +161,7 @@ where
OnEmpty: Get<QueryKind::Query> + 'static,
MaxValues: Get<Option<u32>>,
{
fn try_decode_entire_state() -> Result<usize, &'static str> {
fn try_decode_entire_state() -> Result<usize, TryDecodeEntireStorageError> {
let info = Self::partial_storage_info()
.first()
.cloned()
Expand All @@ -167,7 +188,7 @@ impl<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues> TryDecodeEntireS
OnEmpty: Get<QueryKind::Query> + 'static,
MaxValues: Get<Option<u32>>,
{
fn try_decode_entire_state() -> Result<usize, &'static str> {
fn try_decode_entire_state() -> Result<usize, TryDecodeEntireStorageError> {
let (map_info, counter_info) = match &Self::partial_storage_info()[..] {
[a, b] => (a.clone(), b.clone()),
_ => panic!("Counted map has two storage info items; qed"),
Expand Down Expand Up @@ -201,7 +222,7 @@ impl<Prefix, Hasher1, Key1, Hasher2, Key2, Value, QueryKind, OnEmpty, MaxValues>
OnEmpty: Get<QueryKind::Query> + 'static,
MaxValues: Get<Option<u32>>,
{
fn try_decode_entire_state() -> Result<usize, &'static str> {
fn try_decode_entire_state() -> Result<usize, TryDecodeEntireStorageError> {
let info = Self::partial_storage_info()
.first()
.cloned()
Expand All @@ -220,7 +241,7 @@ where
OnEmpty: Get<QueryKind::Query> + 'static,
MaxValues: Get<Option<u32>>,
{
fn try_decode_entire_state() -> Result<usize, &'static str> {
fn try_decode_entire_state() -> Result<usize, TryDecodeEntireStorageError> {
let info = Self::partial_storage_info()
.first()
.cloned()
Expand All @@ -239,7 +260,7 @@ where
OnEmpty: Get<QueryKind::Query> + 'static,
MaxValues: Get<Option<u32>>,
{
fn try_decode_entire_state() -> Result<usize, &'static str> {
fn try_decode_entire_state() -> Result<usize, TryDecodeEntireStorageError> {
let (map_info, counter_info) = match &Self::partial_storage_info()[..] {
[a, b] => (a.clone(), b.clone()),
_ => panic!("Counted NMap has two storage info items; qed"),
Expand Down