mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 00:01:09 +00:00
Support constructing and submitting V5 transactions (#1931)
* TransactionExtensions basic support for V5 VerifySignature and renames * WIP: subxt-core v5 transaction support * Subxt to support V5 extrinsics * WIP tests failing with wsm trap error * Actually encode mortality to fix tx encode issue * fmt * rename to sign_with_account_and_signature * Add explicit methods for v4 and v5 ext construction * clippy * fix wasm example and no mut self where not needed * fix doc example * another doc fix * Add tests for tx encoding and fix v5 encode issue * add copyright and todo * refactor APIs to have clear v4/v5 split in core and slightly nicer split in subxt proper * rename Partial/SubmittableExtrinsic to *Transaction * Remove SignerT::address since it's not needed * doc fixes * fmt * doc fixes * Fix comment number * Clarify panic behaviour of inject_signature * fmt
This commit is contained in:
+20
-16
@@ -2,10 +2,10 @@
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
use crate::config::signed_extensions::{
|
||||
use crate::config::transaction_extensions::{
|
||||
ChargeAssetTxPayment, ChargeTransactionPayment, CheckNonce,
|
||||
};
|
||||
use crate::config::SignedExtension;
|
||||
use crate::config::TransactionExtension;
|
||||
use crate::dynamic::Value;
|
||||
use crate::{config::Config, error::Error, Metadata};
|
||||
use frame_decode::extrinsics::ExtrinsicExtensions;
|
||||
@@ -13,14 +13,14 @@ use scale_decode::DecodeAsType;
|
||||
|
||||
/// The signed extensions of an extrinsic.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ExtrinsicSignedExtensions<'a, T: Config> {
|
||||
pub struct ExtrinsicTransactionExtensions<'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> {
|
||||
impl<'a, T: Config> ExtrinsicTransactionExtensions<'a, T> {
|
||||
pub(crate) fn new(
|
||||
bytes: &'a [u8],
|
||||
metadata: &'a Metadata,
|
||||
@@ -35,20 +35,22 @@ impl<'a, T: Config> ExtrinsicSignedExtensions<'a, T> {
|
||||
}
|
||||
|
||||
/// Returns an iterator over each of the signed extension details of the extrinsic.
|
||||
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,
|
||||
})
|
||||
pub fn iter(&self) -> impl Iterator<Item = ExtrinsicTransactionExtension<T>> {
|
||||
self.decoded_info
|
||||
.iter()
|
||||
.map(|s| ExtrinsicTransactionExtension {
|
||||
bytes: &self.bytes[s.range()],
|
||||
ty_id: *s.ty(),
|
||||
identifier: s.name(),
|
||||
metadata: self.metadata,
|
||||
_marker: core::marker::PhantomData,
|
||||
})
|
||||
}
|
||||
|
||||
/// Searches through all signed extensions to find a specific one.
|
||||
/// If the Signed Extension is not found `Ok(None)` is returned.
|
||||
/// If the Signed Extension is found but decoding failed `Err(_)` is returned.
|
||||
pub fn find<S: SignedExtension<T>>(&self) -> Result<Option<S::Decoded>, Error> {
|
||||
pub fn find<S: TransactionExtension<T>>(&self) -> Result<Option<S::Decoded>, Error> {
|
||||
for ext in self.iter() {
|
||||
match ext.as_signed_extension::<S>() {
|
||||
// We found a match; return it:
|
||||
@@ -90,7 +92,7 @@ impl<'a, T: Config> ExtrinsicSignedExtensions<'a, T> {
|
||||
|
||||
/// A single signed extension
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ExtrinsicSignedExtension<'a, T: Config> {
|
||||
pub struct ExtrinsicTransactionExtension<'a, T: Config> {
|
||||
bytes: &'a [u8],
|
||||
ty_id: u32,
|
||||
identifier: &'a str,
|
||||
@@ -98,7 +100,7 @@ pub struct ExtrinsicSignedExtension<'a, T: Config> {
|
||||
_marker: core::marker::PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<'a, T: Config> ExtrinsicSignedExtension<'a, T> {
|
||||
impl<'a, T: Config> ExtrinsicTransactionExtension<'a, T> {
|
||||
/// The bytes representing this signed extension.
|
||||
pub fn bytes(&self) -> &'a [u8] {
|
||||
self.bytes
|
||||
@@ -127,7 +129,9 @@ impl<'a, T: Config> ExtrinsicSignedExtension<'a, T> {
|
||||
/// Decodes the bytes of this Signed Extension into its associated `Decoded` type.
|
||||
/// Returns `Ok(None)` if the data we have doesn't match the Signed Extension we're asking to
|
||||
/// decode with.
|
||||
pub fn as_signed_extension<S: SignedExtension<T>>(&self) -> Result<Option<S::Decoded>, Error> {
|
||||
pub fn as_signed_extension<S: TransactionExtension<T>>(
|
||||
&self,
|
||||
) -> Result<Option<S::Decoded>, Error> {
|
||||
if !S::matches(self.identifier, self.ty_id, self.metadata.types()) {
|
||||
return Ok(None);
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
// see LICENSE for license details.
|
||||
|
||||
use super::BlockError;
|
||||
use crate::blocks::extrinsic_signed_extensions::ExtrinsicSignedExtensions;
|
||||
use crate::blocks::extrinsic_transaction_extensions::ExtrinsicTransactionExtensions;
|
||||
use crate::{
|
||||
config::{Config, Hasher},
|
||||
error::{Error, MetadataError},
|
||||
@@ -232,17 +232,17 @@ where
|
||||
/// They do *not* include the `additional` signed bytes that are used as part of the payload that is signed.
|
||||
///
|
||||
/// Note: Returns `None` if the extrinsic is not signed.
|
||||
pub fn signed_extensions_bytes(&self) -> Option<&[u8]> {
|
||||
pub fn transaction_extensions_bytes(&self) -> Option<&[u8]> {
|
||||
self.decoded_info()
|
||||
.transaction_extension_payload()
|
||||
.map(|t| &self.bytes()[t.range()])
|
||||
}
|
||||
|
||||
/// Returns `None` if the extrinsic is not signed.
|
||||
pub fn signed_extensions(&self) -> Option<ExtrinsicSignedExtensions<'_, T>> {
|
||||
pub fn transaction_extensions(&self) -> Option<ExtrinsicTransactionExtensions<'_, T>> {
|
||||
self.decoded_info()
|
||||
.transaction_extension_payload()
|
||||
.map(|t| ExtrinsicSignedExtensions::new(self.bytes(), &self.metadata, t))
|
||||
.map(|t| ExtrinsicTransactionExtensions::new(self.bytes(), &self.metadata, t))
|
||||
}
|
||||
|
||||
/// The index of the pallet that the extrinsic originated from.
|
||||
@@ -544,7 +544,7 @@ mod tests {
|
||||
);
|
||||
|
||||
// Encoded TX ready to submit.
|
||||
let tx_encoded = crate::tx::create_unsigned::<SubstrateConfig, _>(&tx, &metadata)
|
||||
let tx_encoded = crate::tx::create_v4_unsigned::<SubstrateConfig, _>(&tx, &metadata)
|
||||
.expect("Valid dynamic parameters are provided");
|
||||
|
||||
// Extrinsic details ready to decode.
|
||||
@@ -575,7 +575,7 @@ mod tests {
|
||||
Value::string("SomeValue"),
|
||||
],
|
||||
);
|
||||
let tx_encoded = crate::tx::create_unsigned::<SubstrateConfig, _>(&tx, &metadata)
|
||||
let tx_encoded = crate::tx::create_v4_unsigned::<SubstrateConfig, _>(&tx, &metadata)
|
||||
.expect("Valid dynamic parameters are provided");
|
||||
|
||||
// Note: `create_unsigned` produces the extrinsic bytes by prefixing the extrinsic length.
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
//! # ]);
|
||||
//! ```
|
||||
|
||||
mod extrinsic_signed_extensions;
|
||||
mod extrinsic_transaction_extensions;
|
||||
mod extrinsics;
|
||||
mod static_extrinsic;
|
||||
|
||||
@@ -74,7 +74,9 @@ use crate::Metadata;
|
||||
use alloc::vec::Vec;
|
||||
|
||||
pub use crate::error::BlockError;
|
||||
pub use extrinsic_signed_extensions::{ExtrinsicSignedExtension, ExtrinsicSignedExtensions};
|
||||
pub use extrinsic_transaction_extensions::{
|
||||
ExtrinsicTransactionExtension, ExtrinsicTransactionExtensions,
|
||||
};
|
||||
pub use extrinsics::{ExtrinsicDetails, ExtrinsicMetadataDetails, Extrinsics, FoundExtrinsic};
|
||||
pub use static_extrinsic::StaticExtrinsic;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user