Skip to content

Commit 8329990

Browse files
authored
v0.50.0: Integrate frame-decode, redo storage APIs and break up Error. (#2100)
* WIP integrating new frame-decode and working out new storage APIS * WIP: first pass adding new storage things to subxt-core * Second pass over Address type and start impl in Subxt * WIP new storage APIs * WIP New storage APIs roughly completed, lots of errors still * Remove PlainorMap enum; plain and map values now use same struct to simplify usage * Begin 'fixing' errors * WIP splitting errors and tidying payload/address traits * Get subxt-core compiling * Small fixes in subxt-core and remove metadata mod * subxt-core: cargo check --all-targets passes * Fix test * WIP starting to update subxt from subxt-core changes * WIP splitting up subxt errors into smaller variants * WIP errors: add DispatchError errors * Port new Storage APIs to subxt-core * cargo check -p subxt passes * Quick-fix errors in subxt-cli (explore subcommand) * fmt * Finish fixing codegen up and start fixing examples * get Subxt examples compiling and bytes_at for constants * Add some arcs to limit lifetimes in subxt/subxt-core storage APIs * A little Arcing to allow more method chaining in Storage APIs, aligning with Subxt * Update codegen test * cargo check --all-targets passing * cargo check --features 'unstable-light-client' passing * clippy * Remove unused dep in subxt * use published frame-decode * fix wasm-example * Add new tx extension to fix daily tests * Remove unused subxt_core::dynamic::DecodedValue type * Update book to match changes * Update docs to fix more broken bits * Add missing docs * fmt * allow larger result errs for now * Add missing alloc imports in subxt-core * Fix doc tests and fix bug getting constant info * Fix V14 -> Metadata transform for storage & constants * Fix parachain example * Fix FFI example * BlockLength decodes t ostruct, not u128 * use fetch/iter shorthands rather than entry in most storage tests * Fix some integration tests * Fix Runtime codegen tests * Expose the dynamic custom_value selecter and use in a UI test * Update codegen metadata * Tidy CLI storage query and support (str,str) as a storage address * Add (str,str) as valid constant address too * Show string tuple in constants example * Via the magic of traits, avoid needing any clones of queries/addresses and accept references to them * clippy
1 parent 7b4b239 commit 8329990

File tree

138 files changed

+11015
-16224
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

138 files changed

+11015
-16224
lines changed

Cargo.lock

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ darling = "0.20.10"
8181
derive-where = "1.2.7"
8282
either = { version = "1.13.0", default-features = false }
8383
finito = { version = "0.1.0", default-features = false }
84-
frame-decode = { version = "0.10.0", default-features = false }
84+
frame-decode = { version = "0.11.1", default-features = false }
8585
frame-metadata = { version = "23.0.0", default-features = false }
8686
futures = { version = "0.3.31", default-features = false, features = ["std"] }
8787
getrandom = { version = "0.2", default-features = false }
@@ -98,12 +98,12 @@ proc-macro2 = "1.0.86"
9898
quote = "1.0.37"
9999
regex = { version = "1.11.0", default-features = false }
100100
scale-info = { version = "2.11.4", default-features = false }
101-
scale-value = { version = "0.18.0", default-features = false }
101+
scale-value = { version = "0.18.1", default-features = false }
102102
scale-bits = { version = "0.7.0", default-features = false }
103103
scale-decode = { version = "0.16.0", default-features = false }
104104
scale-encode = { version = "0.10.0", default-features = false }
105105
scale-type-resolver = { version = "0.2.0" }
106-
scale-info-legacy = { version = "0.2.3" }
106+
scale-info-legacy = { version = "0.2.4" }
107107
scale-typegen = "0.11.1"
108108
scale-typegen-description = "0.11.0"
109109
serde = { version = "1.0.210", default-features = false, features = ["derive"] }

cli/src/commands/diff.rs

Lines changed: 14 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,6 @@ struct StorageEntryDiff {
215215
key_different: bool,
216216
value_different: bool,
217217
default_different: bool,
218-
modifier_different: bool,
219218
}
220219

221220
impl StorageEntryDiff {
@@ -225,41 +224,32 @@ impl StorageEntryDiff {
225224
metadata_1: &Metadata,
226225
metadata_2: &Metadata,
227226
) -> Self {
228-
let value_1_ty_id = storage_entry_1.entry_type().value_ty();
227+
let value_1_ty_id = storage_entry_1.value_ty();
229228
let value_1_hash = metadata_1
230229
.type_hash(value_1_ty_id)
231230
.expect("type is in metadata; qed");
232-
let value_2_ty_id = storage_entry_2.entry_type().value_ty();
231+
let value_2_ty_id = storage_entry_2.value_ty();
233232
let value_2_hash = metadata_2
234233
.type_hash(value_2_ty_id)
235234
.expect("type is in metadata; qed");
236235
let value_different = value_1_hash != value_2_hash;
237236

238-
let key_1_hash = storage_entry_1
239-
.entry_type()
240-
.key_ty()
241-
.map(|key_ty| {
242-
metadata_1
243-
.type_hash(key_ty)
244-
.expect("type is in metadata; qed")
245-
})
246-
.unwrap_or_default();
247-
let key_2_hash = storage_entry_2
248-
.entry_type()
249-
.key_ty()
250-
.map(|key_ty| {
251-
metadata_2
252-
.type_hash(key_ty)
253-
.expect("type is in metadata; qed")
254-
})
255-
.unwrap_or_default();
256-
let key_different = key_1_hash != key_2_hash;
237+
let key_parts_same = storage_entry_1.keys().len() == storage_entry_2.keys().len()
238+
&& storage_entry_1
239+
.keys()
240+
.zip(storage_entry_2.keys())
241+
.all(|(a, b)| {
242+
let a_hash = metadata_1.type_hash(a.key_id).expect("type is in metadata");
243+
let b_hash = metadata_2.type_hash(b.key_id).expect("type is in metadata");
244+
a.hasher == b.hasher && a_hash == b_hash
245+
});
246+
247+
let key_different = !key_parts_same;
257248

258249
StorageEntryDiff {
259250
key_different,
260251
value_different,
261-
default_different: storage_entry_1.default_bytes() != storage_entry_2.default_bytes(),
262-
modifier_different: storage_entry_1.modifier() != storage_entry_2.modifier(),
252+
default_different: storage_entry_1.default_value() != storage_entry_2.default_value(),
263253
}
264254
}
265255

@@ -271,9 +261,6 @@ impl StorageEntryDiff {
271261
if self.value_different {
272262
strings.push("value type");
273263
}
274-
if self.modifier_different {
275-
strings.push("modifier");
276-
}
277264
if self.default_different {
278265
strings.push("default value");
279266
}

cli/src/commands/explore/pallets/calls.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use subxt::utils::H256;
1212
use subxt::{
1313
OfflineClient,
1414
config::SubstrateConfig,
15-
metadata::{Metadata, types::PalletMetadata},
15+
metadata::{Metadata, PalletMetadata},
1616
};
1717

1818
use crate::utils::{

cli/src/commands/explore/pallets/constants.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use clap::Args;
22
use color_eyre::eyre::eyre;
33
use indoc::{formatdoc, writedoc};
44
use scale_typegen_description::type_description;
5-
use subxt::metadata::{Metadata, types::PalletMetadata};
5+
use subxt::metadata::{Metadata, PalletMetadata};
66

77
use crate::utils::{Indent, SyntaxHighlight, first_paragraph_of_docs, format_scale_value};
88

cli/src/commands/explore/pallets/events.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use clap::Args;
22
use color_eyre::eyre::eyre;
33
use indoc::{formatdoc, writedoc};
44
use scale_info::{Variant, form::PortableForm};
5-
use subxt::metadata::{Metadata, types::PalletMetadata};
5+
use subxt::metadata::{Metadata, PalletMetadata};
66

77
use crate::utils::{Indent, fields_description, first_paragraph_of_docs};
88

cli/src/commands/explore/pallets/storage.rs

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,11 @@
11
use clap::Args;
2-
use color_eyre::{
3-
eyre::{bail, eyre},
4-
owo_colors::OwoColorize,
5-
};
2+
use color_eyre::{eyre::bail, owo_colors::OwoColorize};
63
use indoc::{formatdoc, writedoc};
74
use scale_typegen_description::type_description;
85
use scale_value::Value;
96
use std::fmt::Write;
107
use std::write;
11-
use subxt::metadata::{
12-
Metadata,
13-
types::{PalletMetadata, StorageEntryType, StorageMetadata},
14-
};
8+
use subxt::metadata::{Metadata, PalletMetadata, StorageMetadata};
159

1610
use crate::utils::{
1711
FileOrUrl, Indent, SyntaxHighlight, create_client, first_paragraph_of_docs,
@@ -75,12 +69,7 @@ pub async fn explore_storage(
7569
);
7670
};
7771

78-
let (return_ty_id, key_ty_id) = match storage.entry_type() {
79-
StorageEntryType::Plain(value) => (*value, None),
80-
StorageEntryType::Map {
81-
value_ty, key_ty, ..
82-
} => (*value_ty, Some(*key_ty)),
83-
};
72+
let return_ty_id = storage.value_ty();
8473

8574
let key_value_placeholder = "<KEY_VALUE>".blue();
8675

@@ -114,15 +103,30 @@ pub async fn explore_storage(
114103
"}?;
115104

116105
// inform user about shape of the key if it can be provided:
117-
if let Some(key_ty_id) = key_ty_id {
118-
let key_ty_description = type_description(key_ty_id, metadata.types(), true)
119-
.expect("No type Description")
120-
.indent(4)
121-
.highlight();
106+
let storage_keys = storage.keys().collect::<Vec<_>>();
107+
if !storage_keys.is_empty() {
108+
let key_ty_description = format!(
109+
"({})",
110+
storage_keys
111+
.iter()
112+
.map(|key| type_description(key.key_id, metadata.types(), true)
113+
.expect("No type Description"))
114+
.collect::<Vec<_>>()
115+
.join(", ")
116+
)
117+
.indent(4)
118+
.highlight();
122119

123-
let key_ty_example = type_example(key_ty_id, metadata.types())
124-
.indent(4)
125-
.highlight();
120+
let key_ty_example = format!(
121+
"({})",
122+
storage_keys
123+
.iter()
124+
.map(|key| type_example(key.key_id, metadata.types()).to_string())
125+
.collect::<Vec<_>>()
126+
.join(", ")
127+
)
128+
.indent(4)
129+
.highlight();
126130

127131
writedoc! {output, "
128132
@@ -144,7 +148,8 @@ pub async fn explore_storage(
144148
return Ok(());
145149
}
146150

147-
let storage_entry_keys: Vec<Value> = match (!trailing_args.is_empty(), key_ty_id.is_some()) {
151+
let storage_entry_keys: Vec<Value> = match (!trailing_args.is_empty(), !storage_keys.is_empty())
152+
{
148153
// keys provided, keys not needed.
149154
(true, false) => {
150155
let trailing_args_str = trailing_args.join(" ");
@@ -190,18 +195,17 @@ pub async fn explore_storage(
190195
// construct the client:
191196
let client = create_client(&file_or_url).await?;
192197

193-
let storage_query = subxt::dynamic::storage(pallet_name, storage.name(), storage_entry_keys);
194-
let decoded_value_thunk_or_none = client
198+
// Fetch the value:
199+
let storage_value = client
195200
.storage()
196201
.at_latest()
197202
.await?
198-
.fetch(&storage_query)
199-
.await?;
203+
.fetch((pallet_name, storage.name()), storage_entry_keys)
204+
.await?
205+
.decode()?;
200206

201-
let decoded_value_thunk =
202-
decoded_value_thunk_or_none.ok_or(eyre!("Value not found in storage."))?;
207+
let value = storage_value.to_string().highlight();
203208

204-
let value = decoded_value_thunk.to_value()?.to_string().highlight();
205209
writedoc! {output, "
206210
207211
The value of the storage entry is:

cli/src/commands/explore/runtime_apis/mod.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -101,15 +101,13 @@ pub async fn run<'a>(
101101
return format!("The method does not require an {input_value_placeholder}");
102102
}
103103

104-
let fields: Vec<(Option<&str>, u32)> = method
105-
.inputs()
106-
.map(|f| (Some(f.name.as_str()), f.ty))
107-
.collect();
104+
let fields: Vec<(Option<&str>, u32)> =
105+
method.inputs().map(|f| (Some(&*f.name), f.id)).collect();
108106
let fields_description =
109107
fields_description(&fields, method.name(), metadata.types()).indent(4);
110108

111109
let fields_example =
112-
fields_composite_example(method.inputs().map(|e| e.ty), metadata.types())
110+
fields_composite_example(method.inputs().map(|e| e.id), metadata.types())
113111
.indent(4)
114112
.highlight();
115113

@@ -164,13 +162,14 @@ pub async fn run<'a>(
164162
{value_str}
165163
"}?;
166164
// encode, then decode. This ensures that the scale value is of the correct shape for the param:
167-
let bytes = value.encode_as_type(ty.ty, metadata.types())?;
168-
let value = Value::decode_as_type(&mut &bytes[..], ty.ty, metadata.types())?;
165+
let bytes = value.encode_as_type(ty.id, metadata.types())?;
166+
let value = Value::decode_as_type(&mut &bytes[..], ty.id, metadata.types())?;
169167
Ok(value)
170168
})
171169
.collect::<color_eyre::Result<Vec<Value>>>()?;
172170

173-
let method_call = subxt::dynamic::runtime_api_call(api_name, method.name(), args_data);
171+
let method_call =
172+
subxt::dynamic::runtime_api_call::<_, Value>(api_name, method.name(), args_data);
174173
let client = create_client(&file_or_url).await?;
175174
let output_value = client
176175
.runtime_api()
@@ -179,7 +178,7 @@ pub async fn run<'a>(
179178
.call(method_call)
180179
.await?;
181180

182-
let output_value = output_value.to_value()?.to_string().highlight();
181+
let output_value = output_value.to_string().highlight();
183182
writedoc! {output, "
184183
185184
Returned value:

clippy.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
# result_large_err lint complains if error variant is 128 bytes or more by default.
22
# Our error is. Let's up this limit a bit for now to avoid lots of warnings.
3-
large-error-threshold = 256
3+
large-error-threshold = 512

codegen/src/api/custom_values.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,17 @@ fn generate_custom_value_fn(
5757
.types()
5858
.resolve(custom_value.type_id())
5959
.is_some();
60+
6061
let (return_ty, decodable) = if type_is_valid {
6162
let return_ty = type_gen
6263
.resolve_type_path(custom_value.type_id())
6364
.expect("type is in metadata; qed")
6465
.to_token_stream(type_gen.settings());
65-
let decodable = quote!(#crate_path::utils::Yes);
66+
let decodable = quote!(#crate_path::utils::Maybe);
6667
(return_ty, decodable)
6768
} else {
6869
// if type registry does not contain the type, we can just return the Encoded scale bytes.
69-
(quote!(()), quote!(()))
70+
(quote!(()), quote!(#crate_path::utils::No))
7071
};
7172

7273
Some(quote!(

0 commit comments

Comments
 (0)