Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
b48d2ee
Update frame-metadata to the latest branch
lexnv Jun 29, 2023
dde7411
metadata: Add outer enum types
lexnv Jun 29, 2023
326af9b
metadata: Extend the extrinsic with address,call,sign,extra types
lexnv Jun 29, 2023
db542dc
Codegen test Event, Error and Call for outer enums
lexnv Jun 29, 2023
53e3d93
Revert "Codegen test Event, Error and Call for outer enums"
lexnv Jun 30, 2023
f2d1c92
Update frame-metadata from the latest release
lexnv Jun 30, 2023
d401f21
Update scale-info
lexnv Jul 3, 2023
e0be009
codegen/error: Support v15 message
lexnv Jul 3, 2023
8a9e0cf
metadata: Convert v14 to v15
lexnv Jul 3, 2023
f1332b7
metadata/retain: Adjust to extrinsic type for V15
lexnv Jul 3, 2023
d035bb5
metadata/validation: Adjust hashing for extrinsic types V15
lexnv Jul 3, 2023
06aa5dc
scripts: Fetch V15 and output codegen for full_client only
lexnv Jul 3, 2023
d094a48
subxt/blocks: Use extrinsic types directly
lexnv Jul 3, 2023
60d38a7
testing: Fetch V15 for build script
lexnv Jul 3, 2023
a994c22
artifacts: Generate from latest polkadot version
lexnv Jul 3, 2023
5e8318c
codegen: Fetch legacy with old API for v14 only
lexnv Jul 4, 2023
fa0c044
rpc: Fetch metadata versions
lexnv Jul 4, 2023
5093d22
client: Fetch latest unstable then V15 then V14
lexnv Jul 4, 2023
16562e1
testing: Adjust testing API to latest interface
lexnv Jul 4, 2023
c503732
Merge remote-tracking branch 'origin/master' into lexnv/stable_v15
lexnv Jul 4, 2023
d719e8b
Adjust clippy
lexnv Jul 4, 2023
51beb8b
metadata: Generate the `RuntimeError` type for V14
lexnv Jul 4, 2023
8bd8fdb
Remove testing files
lexnv Jul 5, 2023
0767c3c
testing/staking: Remove controller account from bond
lexnv Jul 5, 2023
1f2c9ba
metadata/validation: Use specific variants for hashing RuntimeCall
lexnv Jul 5, 2023
e970529
XXX: Custom Substrate binary: must revert with next release
lexnv Jul 5, 2023
b18a5a0
XXX: To revert: CI use hardcoded substrate
lexnv Jul 5, 2023
a11308a
codegen: Use v15 outer enum types
lexnv Jul 6, 2023
b5e6a76
metadata: Retain outer enum types
lexnv Jul 6, 2023
f31289e
codegen: Use outer enum types instead of generating them
lexnv Jul 6, 2023
65d2e69
Update artifacts
lexnv Jul 6, 2023
5d33dec
Revert "XXX: Custom Substrate binary: must revert with next release"
lexnv Jul 6, 2023
e0b3f8a
testing: Include env for dummy wat contracts
lexnv Jul 6, 2023
c89203b
Adjsut clippy
lexnv Jul 6, 2023
bee6d87
ci: Use new link for fetching latest substrate binary
lexnv Jul 6, 2023
11bf5ae
tests: Include dummy RuntimeEvent into test metadata
lexnv Jul 6, 2023
dfb879c
ci: Bump light-client timeout tests to 25min
lexnv Jul 6, 2023
08f230a
metadata/validation: Use specific pallets as provided
lexnv Jul 6, 2023
2ca7bca
testing: Rename metadata constant
lexnv Jul 12, 2023
fb8242a
metadata: Use call_ty instead of signature_ty
lexnv Jul 12, 2023
414270a
metadata: Rename retaining variant function
lexnv Jul 12, 2023
73832bb
metadata: Use Option<&[&str]>
lexnv Jul 12, 2023
d86128d
online_client: Fetch V15 metadata explicitely
lexnv Jul 12, 2023
58af952
Merge remote-tracking branch 'origin/master' into lexnv/stable_v15
lexnv Jul 12, 2023
ed786b6
metadata/validation: Include the hash of the outer enum types
lexnv Jul 12, 2023
d8da7fa
metadata: Fix sign typo
lexnv Jul 12, 2023
437a589
artifacts: Update the artifacts
lexnv Jul 12, 2023
a6c57fc
subxt: Remove RootError RootEvent and RootExtrinsic traits
lexnv Jul 12, 2023
ec7f215
Update polkadot.rs
lexnv Jul 12, 2023
9ba48b3
metadata/tests: Ensure outer enum variants are retained
lexnv Jul 12, 2023
8995ad6
scripts: Include multiple pallets for our decoding purposes
lexnv Jul 12, 2023
bc9f66a
subxt: Apply clippy
lexnv Jul 12, 2023
55b7730
artifacts: Update small metadata
lexnv Jul 12, 2023
66a0db0
error: Keep raw bytes for the ModuleError representation
lexnv Jul 12, 2023
a16743a
error: Modify docs to not include links
lexnv Jul 12, 2023
44924fb
subxt/tests: Propagate `RuntimeCall` to outer enums
lexnv Jul 13, 2023
e7f7e51
subxt: Provide proper byte slice for decoding
lexnv Jul 13, 2023
26179a3
Update artifacts
lexnv Jul 13, 2023
09b685c
cli/tests: Adjust expected pallets message
lexnv Jul 13, 2023
525a8c4
metadata: Test conversion from v14 to v15
lexnv Jul 13, 2023
e942f9e
metadata: Fix typo
lexnv Jul 13, 2023
31200a0
Update subxt/src/blocks/extrinsic_types.rs
lexnv Jul 13, 2023
5eee195
Merge remote-tracking branch 'origin/lexnv/stable_v15' into lexnv/sta…
lexnv Jul 13, 2023
089bf56
metadata: Simplify type path for RuntimeError
lexnv Jul 13, 2023
1b77eb1
metadata/validation: Use visited ids per outer enum
lexnv Jul 13, 2023
496e878
error: Remove RawModuleError
lexnv Jul 13, 2023
2d0d30c
Fix new clippy error from updated rust version
lexnv Jul 13, 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
Prev Previous commit
Next Next commit
subxt: Remove RootError RootEvent and RootExtrinsic traits
Signed-off-by: Alexandru Vasile <[email protected]>
  • Loading branch information
lexnv committed Jul 12, 2023
commit a6c57fc33bc4ad4e6ffd672f71037c2bfbe2f5e3
77 changes: 0 additions & 77 deletions codegen/src/api/mod.rs
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nice to see the codegen simplifications here :)

Original file line number Diff line number Diff line change
Expand Up @@ -381,58 +381,6 @@ impl RuntimeGenerator {
})
.collect::<Result<Vec<_>, CodegenError>>()?;

let root_event_if_arms = self.metadata.pallets().filter_map(|p| {
let variant_name_str = &p.name();
let variant_name = format_ident!("{}", variant_name_str);
let mod_name = format_ident!("{}", variant_name_str.to_string().to_snake_case());

p.event_ty_id().map(|_| {
// An 'if' arm for the RootEvent impl to match this variant name:
quote! {
if pallet_name == #variant_name_str {
return Ok(Event::#variant_name(#mod_name::Event::decode_with_metadata(
&mut &*pallet_bytes,
pallet_ty,
metadata
)?));
}
}
})
});

let root_extrinsic_if_arms = self.metadata.pallets().filter_map(|p| {
let variant_name_str = p.name();
let variant_name = format_ident!("{}", variant_name_str);
let mod_name = format_ident!("{}", variant_name_str.to_string().to_snake_case());
p.call_ty_id().map(|_| {
// An 'if' arm for the RootExtrinsic impl to match this variant name:
quote! {
if pallet_name == #variant_name_str {
return Ok(Call::#variant_name(#mod_name::Call::decode_with_metadata(
&mut &*pallet_bytes,
pallet_ty,
metadata
)?));
}
}
})
});

let root_error_if_arms = self.metadata.pallets().filter_map(|p| {
let variant_name_str = &p.name();
let variant_name = format_ident!("{}", variant_name_str);
let mod_name = format_ident!("{}", variant_name_str.to_string().to_snake_case());

p.error_ty_id().map(|type_id| {
quote! {
if pallet_name == #variant_name_str {
let variant_error = #mod_name::Error::decode_with_metadata(cursor, #type_id, metadata)?;
return Ok(Error::#variant_name(variant_error));
}
}
})
});

let mod_ident = &item_mod_ir.ident;
let pallets_with_constants: Vec<_> = pallets_with_mod_names
.iter()
Expand Down Expand Up @@ -499,37 +447,12 @@ impl RuntimeGenerator {
/// The outer event enum.
pub type Event = #event_path;

impl #crate_path::events::RootEvent for Event {
fn root_event(pallet_bytes: &[u8], pallet_name: &str, pallet_ty: u32, metadata: &#crate_path::Metadata) -> Result<Self, #crate_path::Error> {
use #crate_path::metadata::DecodeWithMetadata;
#( #root_event_if_arms )*
Err(#crate_path::ext::scale_decode::Error::custom(format!("Pallet name '{}' not found in root Event enum", pallet_name)).into())
}
}

/// The outer extrinsic enum.
pub type Call = #call_path;

impl #crate_path::blocks::RootExtrinsic for Call {
fn root_extrinsic(pallet_bytes: &[u8], pallet_name: &str, pallet_ty: u32, metadata: &#crate_path::Metadata) -> Result<Self, #crate_path::Error> {
use #crate_path::metadata::DecodeWithMetadata;
#( #root_extrinsic_if_arms )*
Err(#crate_path::ext::scale_decode::Error::custom(format!("Pallet name '{}' not found in root Call enum", pallet_name)).into())
}
}

/// The outer error enum representing the DispatchError's Module variant.
pub type Error = #error_path;

impl #crate_path::error::RootError for Error {
fn root_error(pallet_bytes: &[u8], pallet_name: &str, metadata: &#crate_path::Metadata) -> Result<Self, #crate_path::Error> {
use #crate_path::metadata::DecodeWithMetadata;
let cursor = &mut &pallet_bytes[..];
#( #root_error_if_arms )*
Err(#crate_path::ext::scale_decode::Error::custom(format!("Pallet name '{}' not found in root Error enum", pallet_name)).into())
}
}

pub fn constants() -> ConstantsApi {
ConstantsApi
}
Expand Down
63 changes: 10 additions & 53 deletions subxt/src/blocks/extrinsic_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::{

use codec::Decode;
use derivative::Derivative;
use scale_decode::DecodeAsFields;
use scale_decode::{DecodeAsFields, DecodeAsType};
use std::sync::Arc;

/// Trait to uniquely identify the extrinsic's identity from the runtime metadata.
Expand All @@ -36,23 +36,6 @@ pub trait StaticExtrinsic: DecodeAsFields {
}
}

/// This trait is implemented on the statically generated root extrinsic type, so that we're able
/// to decode it properly via a pallet that impls `DecodeAsMetadata`. This is necessary
/// because the "root extrinsic" type is generated using pallet info but doesn't actually exist in the
/// metadata types, so we have no easy way to decode things into it via type information and need a
/// little help via codegen.
#[doc(hidden)]
pub trait RootExtrinsic: Sized {
/// Given details of the pallet extrinsic we want to decode, and the name of the pallet, try to hand
/// back a "root extrinsic".
fn root_extrinsic(
pallet_bytes: &[u8],
pallet_name: &str,
pallet_extrinsic_ty: u32,
metadata: &Metadata,
) -> Result<Self, Error>;
}

/// The body of a block.
pub struct Extrinsics<T: Config, C> {
client: C,
Expand Down Expand Up @@ -416,22 +399,17 @@ where
}
}

/// Attempt to decode these [`ExtrinsicDetails`] into a root extrinsic type (which includes
/// Attempt to decode these [`ExtrinsicDetails`] into a outer call enum type (which includes
/// the pallet and extrinsic enum variants as well as the extrinsic fields). A compatible
/// type for this is exposed via static codegen as a root level `Call` type.
pub fn as_root_extrinsic<E: RootExtrinsic>(&self) -> Result<E, Error> {
let md = self.extrinsic_metadata()?;
let pallet_extrinsic_ty = md.pallet.call_ty_id().ok_or_else(|| {
Error::Metadata(MetadataError::CallTypeNotFoundInPallet(md.pallet.index()))
})?;

// Ignore root enum index.
E::root_extrinsic(
&self.call_bytes()[1..],
md.pallet.name(),
pallet_extrinsic_ty,
&self.metadata,
)
pub fn as_root_extrinsic<E: DecodeAsType>(&self) -> Result<E, Error> {
let decoded = E::decode_as_type(
&mut &self.call_bytes()[..],
self.metadata.outer_enums().call_enum_ty(),
self.metadata.types(),
)?;

Ok(decoded)
}
}

Expand Down Expand Up @@ -621,27 +599,6 @@ mod tests {
Test(Pallet),
}

// We need this in order to be able to decode into a root extrinsic type:
impl RootExtrinsic for RuntimeCall {
fn root_extrinsic(
mut pallet_bytes: &[u8],
pallet_name: &str,
pallet_extrinsic_ty: u32,
metadata: &Metadata,
) -> Result<Self, Error> {
if pallet_name == "Test" {
return Ok(RuntimeCall::Test(Pallet::decode_with_metadata(
&mut pallet_bytes,
pallet_extrinsic_ty,
metadata,
)?));
}
panic!(
"Asked for pallet name '{pallet_name}', which isn't in our test RuntimeCall type"
)
}
}

// The calls of the pallet.
#[allow(unused)]
#[derive(
Expand Down
4 changes: 1 addition & 3 deletions subxt/src/blocks/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,4 @@ mod extrinsic_types;

pub use block_types::{Block, BlockBody};
pub use blocks_client::{subscribe_to_block_headers_filling_in_gaps, BlocksClient};
pub use extrinsic_types::{
ExtrinsicDetails, ExtrinsicEvents, Extrinsics, RootExtrinsic, StaticExtrinsic,
};
pub use extrinsic_types::{ExtrinsicDetails, ExtrinsicEvents, Extrinsics, StaticExtrinsic};
20 changes: 10 additions & 10 deletions subxt/src/error/dispatch_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@

use crate::metadata::{DecodeWithMetadata, Metadata};
use core::fmt::Debug;
use scale_decode::visitor::DecodeAsTypeResult;
use scale_decode::{visitor::DecodeAsTypeResult, DecodeAsType};
use std::borrow::Cow;

use super::{Error, MetadataError};
use crate::error::RootError;

/// An error dispatching a transaction.
#[derive(Debug, thiserror::Error, PartialEq, Eq)]
Expand Down Expand Up @@ -167,14 +166,15 @@ impl ModuleError {
self.raw
}

/// Attempts to decode the ModuleError into a value implementing the trait `RootError`
/// where the actual type of value is the generated top level enum `Error`.
pub fn as_root_error<E: RootError>(&self) -> Result<E, Error> {
E::root_error(
&self.raw.error,
self.details()?.pallet.name(),
&self.metadata,
)
/// Attempts to decode the ModuleError into the top outer Error enum.
pub fn as_root_error<E: DecodeAsType>(&self) -> Result<E, Error> {
let decoded = E::decode_as_type(
&mut &self.raw.error[..],
self.metadata.outer_enums().error_enum_ty(),
self.metadata.types(),
)?;

Ok(decoded)
}
}

Expand Down
12 changes: 0 additions & 12 deletions subxt/src/error/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,15 +225,3 @@ pub enum MetadataError {
#[error("The generated code is not compatible with the node")]
IncompatibleCodegen,
}

/// This trait is implemented on the statically generated root ModuleError type
#[doc(hidden)]
pub trait RootError: Sized {
/// Given details of the pallet error we want to decode
fn root_error(
// typically a [u8; 4] encodes the error of a pallet
pallet_bytes: &[u8],
pallet_name: &str,
metadata: &Metadata,
) -> Result<Self, Error>;
}
66 changes: 11 additions & 55 deletions subxt/src/events/events_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use crate::{
};
use codec::{Compact, Decode};
use derivative::Derivative;
use scale_decode::DecodeAsType;
use std::sync::Arc;

/// A collection of events obtained from a block, bundled with the necessary
Expand Down Expand Up @@ -203,8 +204,6 @@ pub struct EventDetails<T: Config> {
all_bytes: Arc<[u8]>,
// start of the bytes (phase, pallet/variant index and then fields and then topic to follow).
start_idx: usize,
// start of the event (ie pallet/variant index and then the fields and topic after).
event_start_idx: usize,
// start of the fields (ie after phase and pallet/variant index).
event_fields_start_idx: usize,
// end of the fields.
Expand All @@ -227,8 +226,6 @@ impl<T: Config> EventDetails<T> {

let phase = Phase::decode(input)?;

let event_start_idx = all_bytes.len() - input.len();

let pallet_index = u8::decode(input)?;
let variant_index = u8::decode(input)?;

Expand Down Expand Up @@ -270,7 +267,6 @@ impl<T: Config> EventDetails<T> {
phase,
index,
start_idx,
event_start_idx,
event_fields_start_idx,
event_fields_end_idx,
end_idx,
Expand Down Expand Up @@ -386,20 +382,16 @@ impl<T: Config> EventDetails<T> {
/// Attempt to decode these [`EventDetails`] into a root event type (which includes
/// the pallet and event enum variants as well as the event fields). A compatible
/// type for this is exposed via static codegen as a root level `Event` type.
pub fn as_root_event<E: RootEvent>(&self) -> Result<E, Error> {
let ev_metadata = self.event_metadata();
let pallet_bytes = &self.all_bytes[self.event_start_idx + 1..self.event_fields_end_idx];
let pallet_event_ty = ev_metadata
.pallet
.event_ty_id()
.ok_or_else(|| MetadataError::EventTypeNotFoundInPallet(ev_metadata.pallet.index()))?;

E::root_event(
pallet_bytes,
self.pallet_name(),
pallet_event_ty,
&self.metadata,
)
pub fn as_root_event<E: DecodeAsType>(&self) -> Result<E, Error> {
let bytes = &self.all_bytes[self.start_idx + 1..self.event_fields_end_idx];

let decoded = E::decode_as_type(
&mut &bytes[..],
self.metadata.outer_enums().event_enum_ty(),
self.metadata.types(),
)?;

Ok(decoded)
}

/// Return the topics associated with this event.
Expand All @@ -414,23 +406,6 @@ pub struct EventMetadataDetails<'a> {
pub variant: &'a scale_info::Variant<scale_info::form::PortableForm>,
}

/// This trait is implemented on the statically generated root event type, so that we're able
/// to decode it properly via a pallet event that impls `DecodeAsMetadata`. This is necessary
/// becasue the "root event" type is generated using pallet info but doesn't actually exist in the
/// metadata types, so we have no easy way to decode things into it via type information and need a
/// little help via codegen.
#[doc(hidden)]
pub trait RootEvent: Sized {
/// Given details of the pallet event we want to decode, and the name of the pallet, try to hand
/// back a "root event".
fn root_event(
pallet_bytes: &[u8],
pallet_name: &str,
pallet_event_ty: u32,
metadata: &Metadata,
) -> Result<Self, Error>;
}

/// Event related test utilities used outside this module.
#[cfg(test)]
pub(crate) mod test_utils {
Expand Down Expand Up @@ -463,25 +438,6 @@ pub(crate) mod test_utils {
Test(Ev),
}

// We need this in order to be able to decode into a root event type:
impl<Ev: DecodeWithMetadata> RootEvent for AllEvents<Ev> {
fn root_event(
mut bytes: &[u8],
pallet_name: &str,
pallet_event_ty: u32,
metadata: &Metadata,
) -> Result<Self, Error> {
if pallet_name == "Test" {
return Ok(AllEvents::Test(Ev::decode_with_metadata(
&mut bytes,
pallet_event_ty,
metadata,
)?));
}
panic!("Asked for pallet name '{pallet_name}', which isn't in our test AllEvents type")
}
}

/// This encodes to the same format an event is expected to encode to
/// in node System.Events storage.
#[derive(Encode)]
Expand Down
2 changes: 0 additions & 2 deletions subxt/src/events/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ pub use events_client::EventsClient;
pub use events_type::{
EventDetails,
Events,
// Used in codegen but hidden from docs:
RootEvent,
};
use scale_decode::DecodeAsFields;

Expand Down