Skip to content

Commit

Permalink
remove as_pallet_extrinsic and as_pallet_event (paritytech#953)
Browse files Browse the repository at this point in the history
  • Loading branch information
jsdw authored May 12, 2023
1 parent 6087dc0 commit 13b2943
Show file tree
Hide file tree
Showing 4 changed files with 11 additions and 124 deletions.
13 changes: 0 additions & 13 deletions examples/examples/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,6 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
}
}

// Or we can attempt to decode them into a specific arbitraty pallet enum
// (We could also set the output type to Value to dynamically decode, here):
println!("Event details for Balances pallet:");
for event in events.iter() {
let event = event?;

if let Ok(ev) = event.as_pallet_event::<polkadot::balances::Event>() {
println!("{ev:?}");
} else {
continue;
}
}

// Or we can look for specific events which match our statically defined ones:
let transfer_event = events.find_first::<polkadot::balances::events::Transfer>()?;
if let Some(ev) = transfer_event {
Expand Down
44 changes: 5 additions & 39 deletions subxt/src/blocks/extrinsic_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::{
config::{Config, Hasher},
error::{BlockError, Error},
events,
metadata::{DecodeWithMetadata, ExtrinsicMetadata},
metadata::ExtrinsicMetadata,
rpc::types::ChainBlockExtrinsic,
Metadata,
};
Expand Down Expand Up @@ -373,8 +373,7 @@ where
}

/// Decode and provide the extrinsic fields back in the form of a [`scale_value::Composite`]
/// type which represents the named or unnamed fields that were
/// present in the extrinsic.
/// type which represents the named or unnamed fields that were present in the extrinsic.
pub fn field_values(
&self,
) -> Result<scale_value::Composite<scale_value::scale::TypeId>, Error> {
Expand All @@ -390,10 +389,8 @@ where
Ok(decoded)
}

/// Attempt to statically decode these [`ExtrinsicDetails`] into a type representing the extrinsic
/// fields. This leans directly on [`codec::Decode`]. You can also attempt to decode the entirety
/// of the extrinsic using [`Self::as_root_extrinsic()`], which is more lenient because it's able
/// to lean on [`scale_decode::DecodeAsType`].
/// Attempt to decode these [`ExtrinsicDetails`] into a type representing the extrinsic fields.
/// Such types are exposed in the codegen as `pallet_name::calls::types::CallName` types.
pub fn as_extrinsic<E: StaticExtrinsic>(&self) -> Result<Option<E>, Error> {
let extrinsic_metadata = self.extrinsic_metadata()?;
if extrinsic_metadata.pallet() == E::PALLET && extrinsic_metadata.call() == E::CALL {
Expand All @@ -408,24 +405,6 @@ where
}
}

/// Attempt to decode these [`ExtrinsicDetails`] into a pallet extrinsic type (which includes
/// the pallet enum variants as well as the extrinsic fields). These extrinsics can be found in
/// the static codegen under a path like `pallet_name::Call`.
pub fn as_pallet_extrinsic<E: DecodeWithMetadata>(&self) -> Result<E, Error> {
let pallet = self.metadata.pallet(self.pallet_name()?)?;
let extrinsic_ty = pallet.call_ty_id().ok_or_else(|| {
Error::Metadata(crate::metadata::MetadataError::ExtrinsicNotFound(
pallet.index(),
self.variant_index(),
))
})?;

// Ignore the root enum index, so start 1 byte after that:
let decoded =
E::decode_with_metadata(&mut &self.call_bytes()[1..], extrinsic_ty, &self.metadata)?;
Ok(decoded)
}

/// Attempt to decode these [`ExtrinsicDetails`] into a root extrinsic 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.
Expand Down Expand Up @@ -623,6 +602,7 @@ impl<T: Config> ExtrinsicEvents<T> {
#[cfg(test)]
mod tests {
use super::*;
use crate::metadata::DecodeWithMetadata;
use crate::{rpc::types::RuntimeVersion, OfflineClient, PolkadotConfig};
use assert_matches::assert_matches;
use codec::{Decode, Encode};
Expand Down Expand Up @@ -887,20 +867,6 @@ mod tests {
})
);

// Decode the extrinsic to the pallet enum.
let decoded_extrinsic = extrinsic
.as_pallet_extrinsic::<Pallet>()
.expect("can decode extrinsic to pallet enum");

assert_eq!(
decoded_extrinsic,
Pallet::TestCall {
value: 10,
signed: true,
name: "SomeValue".into(),
}
);

// Decode the extrinsic to the extrinsic variant.
let decoded_extrinsic = extrinsic
.as_extrinsic::<TestCallExtrinsic>()
Expand Down
73 changes: 6 additions & 67 deletions subxt/src/events/events_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,8 @@
use super::{Phase, StaticEvent};
use crate::{
client::OnlineClientT,
error::Error,
events::events_client::get_event_bytes,
metadata::{DecodeWithMetadata, EventMetadata},
Config, Metadata,
client::OnlineClientT, error::Error, events::events_client::get_event_bytes,
metadata::EventMetadata, Config, Metadata,
};
use codec::{Compact, Decode};
use derivative::Derivative;
Expand Down Expand Up @@ -325,8 +322,7 @@ impl EventDetails {
}

/// Decode and provide the event fields back in the form of a [`scale_value::Composite`]
/// type which represents the named or unnamed fields that were
/// present in the event.
/// type which represents the named or unnamed fields that were present in the event.
pub fn field_values(
&self,
) -> Result<scale_value::Composite<scale_value::scale::TypeId>, Error> {
Expand All @@ -343,10 +339,8 @@ impl EventDetails {
Ok(decoded)
}

/// Attempt to statically decode these [`EventDetails`] into a type representing the event
/// fields. This leans directly on [`codec::Decode`]. You can also attempt to decode the entirety
/// of the event using [`EventDetails::as_root_event()`], which is more lenient because it's able
/// to lean on [`scale_decode::DecodeAsType`].
/// Attempt to decode these [`EventDetails`] into a type representing the event fields.
/// Such types are exposed in the codegen as `pallet_name::events::EventName` types.
pub fn as_event<E: StaticEvent>(&self) -> Result<Option<E>, Error> {
let ev_metadata = self.event_metadata();
if ev_metadata.pallet() == E::PALLET && ev_metadata.event() == E::EVENT {
Expand All @@ -361,29 +355,6 @@ impl EventDetails {
}
}

/// Attempt to decode these [`EventDetails`] into a pallet event type (which includes
/// the pallet enum variants as well as the event fields). These events can be found in
/// the static codegen under a path like `pallet_name::Event`.
pub fn as_pallet_event<E: DecodeWithMetadata>(&self) -> Result<E, Error> {
let pallet = self.metadata.pallet(self.pallet_name())?;
let event_ty = pallet.event_ty_id().ok_or_else(|| {
Error::Metadata(crate::metadata::MetadataError::EventNotFound(
pallet.index(),
self.variant_index(),
))
})?;

// Ignore the root enum index, so start 1 byte after that:
let start_idx = self.event_start_idx + 1;

let decoded = E::decode_with_metadata(
&mut &self.all_bytes[start_idx..self.event_fields_end_idx],
event_ty,
&self.metadata,
)?;
Ok(decoded)
}

/// 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.
Expand Down Expand Up @@ -427,6 +398,7 @@ pub trait RootEvent: Sized {
#[cfg(test)]
pub(crate) mod test_utils {
use super::*;
use crate::metadata::DecodeWithMetadata;
use crate::{Config, SubstrateConfig};
use codec::Encode;
use frame_metadata::{
Expand Down Expand Up @@ -675,39 +647,6 @@ mod tests {
assert_eq!(decoded_event, AllEvents::Test(event));
}

#[test]
fn statically_decode_single_pallet_event() {
#[derive(Clone, Debug, PartialEq, Decode, Encode, TypeInfo, scale_decode::DecodeAsType)]
enum Event {
A(u8, bool, Vec<String>),
}

// Create fake metadata that knows about our single event, above:
let metadata = metadata::<Event>();

// Encode our events in the format we expect back from a node, and
// construst an Events object to iterate them:
let event = Event::A(1, true, vec!["Hi".into()]);
let events = events::<Event>(
metadata,
vec![event_record(Phase::ApplyExtrinsic(123), event.clone())],
);

let ev = events
.iter()
.next()
.expect("one event expected")
.expect("event should be extracted OK");

// This is the line we're testing; decode into our "pallet event" enum.
let decoded_event = ev
.as_pallet_event::<Event>()
.expect("can decode event into root enum again");

// It should equal the event we put in:
assert_eq!(decoded_event, event);
}

#[test]
fn dynamically_decode_single_event() {
#[derive(Clone, Debug, PartialEq, Decode, Encode, TypeInfo)]
Expand Down
5 changes: 0 additions & 5 deletions testing/integration-tests/src/blocks/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,18 +172,13 @@ async fn decode_extrinsics() {
assert_eq!(block_extrinsics.len(), 2);
let timestamp = block_extrinsics.get(0).unwrap();
timestamp.as_root_extrinsic::<node_runtime::Call>().unwrap();
timestamp
.as_pallet_extrinsic::<node_runtime::runtime_types::pallet_timestamp::pallet::Call>()
.unwrap();
timestamp
.as_extrinsic::<node_runtime::timestamp::calls::types::Set>()
.unwrap();
assert!(!timestamp.is_signed());

let tx = block_extrinsics.get(1).unwrap();
tx.as_root_extrinsic::<node_runtime::Call>().unwrap();
tx.as_pallet_extrinsic::<node_runtime::runtime_types::pallet_balances::pallet::Call>()
.unwrap();
tx.as_extrinsic::<node_runtime::balances::calls::types::Transfer>()
.unwrap();
assert!(tx.is_signed());
Expand Down

0 comments on commit 13b2943

Please sign in to comment.