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

Use frame-decode for core extrinsic decode logic #1785

Merged
merged 19 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ updates:
schedule:
interval: weekly
- package-ecosystem: github-actions
directory: "**/*"
directories:
- "**/*"
schedule:
interval: weekly
17 changes: 17 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ darling = "0.20.10"
derive-where = "1.2.7"
either = { version = "1.13.0", default-features = false }
finito = { version = "0.1.0", default-features = false }
frame-decode = { version = "0.3.0", default-features = false }
frame-metadata = { version = "16.0.0", default-features = false }
futures = { version = "0.3.30", default-features = false, features = ["std"] }
getrandom = { version = "0.2", default-features = false }
Expand Down
1 change: 1 addition & 0 deletions core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ substrate-compat = ["sp-core", "sp-runtime"]

[dependencies]
codec = { package = "parity-scale-codec", workspace = true, default-features = false, features = ["derive"] }
frame-decode = { workspace = true }
scale-info = { workspace = true, default-features = false, features = ["bit-vec"] }
scale-value = { workspace = true, default-features = false }
scale-bits = { workspace = true, default-features = false }
Expand Down
58 changes: 15 additions & 43 deletions core/src/blocks/extrinsic_signed_extensions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,65 +8,40 @@ use crate::config::signed_extensions::{
use crate::config::SignedExtension;
use crate::dynamic::Value;
use crate::{config::Config, error::Error, Metadata};
use frame_decode::extrinsics::ExtrinsicExtensions;
use scale_decode::DecodeAsType;

/// The signed extensions of an extrinsic.
#[derive(Debug, Clone)]
pub struct ExtrinsicSignedExtensions<'a, T: Config> {
bytes: &'a [u8],
metadata: &'a Metadata,
decoded_info: &'a ExtrinsicExtensions<'static, u32>,
_marker: core::marker::PhantomData<T>,
}

impl<'a, T: Config> ExtrinsicSignedExtensions<'a, T> {
pub(crate) fn new(bytes: &'a [u8], metadata: &'a Metadata) -> Self {
pub(crate) fn new(
bytes: &'a [u8],
metadata: &'a Metadata,
decoded_info: &'a ExtrinsicExtensions<'static, u32>,
) -> Self {
Self {
bytes,
metadata,
decoded_info,
_marker: core::marker::PhantomData,
}
}

/// Returns an iterator over each of the signed extension details of the extrinsic.
/// If the decoding of any signed extension fails, an error item is yielded and the iterator stops.
pub fn iter(&self) -> impl Iterator<Item = Result<ExtrinsicSignedExtension<T>, Error>> {
let signed_extension_types = self.metadata.extrinsic().signed_extensions();
let num_signed_extensions = signed_extension_types.len();
let bytes = self.bytes;
let mut index = 0;
let mut byte_start_idx = 0;
let metadata = &self.metadata;

core::iter::from_fn(move || {
if index == num_signed_extensions {
return None;
}

let extension = &signed_extension_types[index];
let ty_id = extension.extra_ty();
let cursor = &mut &bytes[byte_start_idx..];
if let Err(err) = scale_decode::visitor::decode_with_visitor(
cursor,
ty_id,
metadata.types(),
scale_decode::visitor::IgnoreVisitor::new(),
)
.map_err(|e| Error::Decode(e.into()))
{
index = num_signed_extensions; // (such that None is returned in next iteration)
return Some(Err(err));
}
let byte_end_idx = bytes.len() - cursor.len();
let bytes = &bytes[byte_start_idx..byte_end_idx];
byte_start_idx = byte_end_idx;
index += 1;
Some(Ok(ExtrinsicSignedExtension {
bytes,
ty_id,
identifier: extension.identifier(),
metadata,
_marker: core::marker::PhantomData,
}))
pub fn iter(&self) -> impl Iterator<Item = ExtrinsicSignedExtension<T>> {
self.decoded_info.iter().map(|s| ExtrinsicSignedExtension {
bytes: &self.bytes[s.range()],
ty_id: *s.ty(),
identifier: s.name(),
metadata: self.metadata,
_marker: core::marker::PhantomData,
})
}

Expand All @@ -75,9 +50,6 @@ impl<'a, T: Config> ExtrinsicSignedExtensions<'a, T> {
/// If the Signed Extension is found but decoding failed `Err(_)` is returned.
pub fn find<S: SignedExtension<T>>(&self) -> Result<Option<S::Decoded>, Error> {
for ext in self.iter() {
// If we encounter an error while iterating, we won't get any more results
// back, so just return that error as we won't find the signed ext anyway.
let ext = ext?;
match ext.as_signed_extension::<S>() {
// We found a match; return it:
Ok(Some(e)) => return Ok(Some(e)),
Expand Down
Loading
Loading