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

Remove as_pallet_extrinsic and as_pallet_event #953

Merged
merged 1 commit into from
May 12, 2023
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
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