Return ExtrinsicDetails alongside decoded static extrinsics (#1376)

* staic extrinsic details

* adjust example
This commit is contained in:
Tadeo Hepperle
2024-01-18 17:30:34 +01:00
committed by GitHub
parent 05825bed49
commit 6b065ebce7
2 changed files with 38 additions and 25 deletions
+18 -19
View File
@@ -27,29 +27,28 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("Block #{block_number} ({block_hash}):");
let extrinsics = block.extrinsics().await?;
for ext in extrinsics.iter() {
let ext = ext?;
if let Ok(Some(transfer)) = ext.as_extrinsic::<TransferKeepAlive>() {
let Some(extensions) = ext.signed_extensions() else {
panic!("TransferKeepAlive should be signed")
};
for transfer in extrinsics.find::<TransferKeepAlive>() {
let transfer = transfer?;
ext.address_bytes().unwrap();
let addr_bytes = ext
.address_bytes()
.expect("TransferKeepAlive should be signed");
let sender = MultiAddress::<AccountId32, ()>::decode(&mut &addr_bytes[..])
.expect("Decoding should work");
let sender = display_address(&sender);
let receiver = display_address(&transfer.dest);
let value = transfer.value;
let tip = extensions.tip().expect("Should have tip");
let nonce = extensions.nonce().expect("Should have nonce");
let Some(extensions) = transfer.details.signed_extensions() else {
panic!("TransferKeepAlive should be signed")
};
println!(
let addr_bytes = transfer
.details
.address_bytes()
.expect("TransferKeepAlive should be signed");
let sender = MultiAddress::<AccountId32, ()>::decode(&mut &addr_bytes[..])
.expect("Decoding should work");
let sender = display_address(&sender);
let receiver = display_address(&transfer.value.dest);
let value = transfer.value.value;
let tip = extensions.tip().expect("Should have tip");
let nonce = extensions.nonce().expect("Should have nonce");
println!(
" Transfer of {value} DOT:\n {sender} (Tip: {tip}, Nonce: {nonce}) ---> {receiver}",
);
}
}
}
+20 -6
View File
@@ -130,22 +130,30 @@ where
/// Iterate through the extrinsics using metadata to dynamically decode and skip
/// them, and return only those which should decode to the provided `E` type.
/// If an error occurs, all subsequent iterations return `None`.
pub fn find<E: StaticExtrinsic>(&self) -> impl Iterator<Item = Result<E, Error>> + '_ {
self.iter().filter_map(|e| {
e.and_then(|e| e.as_extrinsic::<E>().map_err(Into::into))
.transpose()
pub fn find<E: StaticExtrinsic>(
&self,
) -> impl Iterator<Item = Result<FoundExtrinsic<T, C, E>, Error>> + '_ {
self.iter().filter_map(|res| match res {
Err(err) => Some(Err(err)),
Ok(details) => match details.as_extrinsic::<E>() {
// Failed to decode extrinsic:
Err(err) => Some(Err(err)),
// Extrinsic for a different pallet / different call (skip):
Ok(None) => None,
Ok(Some(value)) => Some(Ok(FoundExtrinsic { details, value })),
},
})
}
/// Iterate through the extrinsics using metadata to dynamically decode and skip
/// them, and return the first extrinsic found which decodes to the provided `E` type.
pub fn find_first<E: StaticExtrinsic>(&self) -> Result<Option<E>, Error> {
pub fn find_first<E: StaticExtrinsic>(&self) -> Result<Option<FoundExtrinsic<T, C, E>>, Error> {
self.find::<E>().next().transpose()
}
/// Iterate through the extrinsics using metadata to dynamically decode and skip
/// them, and return the last extrinsic found which decodes to the provided `Ev` type.
pub fn find_last<E: StaticExtrinsic>(&self) -> Result<Option<E>, Error> {
pub fn find_last<E: StaticExtrinsic>(&self) -> Result<Option<FoundExtrinsic<T, C, E>>, Error> {
self.find::<E>().last().transpose()
}
@@ -479,6 +487,12 @@ where
}
}
/// A Static Extrinsic found in a block coupled with it's details.
pub struct FoundExtrinsic<T: Config, C, E> {
pub details: ExtrinsicDetails<T, C>,
pub value: E,
}
/// Details for the given extrinsic plucked from the metadata.
pub struct ExtrinsicMetadataDetails<'a> {
pub pallet: PalletMetadata<'a>,