Skip to content

Commit

Permalink
Simplify the TxPayload trait a little (#638)
Browse files Browse the repository at this point in the history
* Simplify TxPayload trait; don't need to get names unless validating

* cargo fmt

* Expose a way to create a SubmittableExtrinsic from pre-prepaed tx bytes

* remove unneeded refs
  • Loading branch information
jsdw authored Aug 29, 2022
1 parent 0b2c31e commit 5ff8493
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 43 deletions.
43 changes: 28 additions & 15 deletions subxt/src/tx/tx_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,14 @@ impl<T: Config, C: OfflineClientT<T>> TxClient<T, C> {
where
Call: TxPayload,
{
if let Some(actual_hash) = call.validation_hash() {
if let Some(details) = call.validation_details() {
let metadata = self.client.metadata();
let expected_hash =
metadata.call_hash(call.pallet_name(), call.call_name())?;
if actual_hash != expected_hash {
metadata.call_hash(details.pallet_name, details.call_name)?;
if details.hash != expected_hash {
return Err(crate::metadata::MetadataError::IncompatibleCallMetadata(
call.pallet_name().into(),
call.call_name().into(),
details.pallet_name.into(),
details.call_name.into(),
)
.into())
}
Expand Down Expand Up @@ -114,11 +114,10 @@ impl<T: Config, C: OfflineClientT<T>> TxClient<T, C> {
};

// Wrap in Encoded to ensure that any more "encode" calls leave it in the right state.
Ok(SubmittableExtrinsic {
client: self.client.clone(),
encoded: Encoded(extrinsic),
marker: std::marker::PhantomData,
})
Ok(SubmittableExtrinsic::from_bytes(
self.client.clone(),
extrinsic,
))
}

/// Creates a raw signed extrinsic without submitting it.
Expand Down Expand Up @@ -202,11 +201,10 @@ impl<T: Config, C: OfflineClientT<T>> TxClient<T, C> {

// Wrap in Encoded to ensure that any more "encode" calls leave it in the right state.
// maybe we can just return the raw bytes..
Ok(SubmittableExtrinsic {
client: self.client.clone(),
encoded: Encoded(extrinsic),
marker: std::marker::PhantomData,
})
Ok(SubmittableExtrinsic::from_bytes(
self.client.clone(),
extrinsic,
))
}
}

Expand Down Expand Up @@ -330,6 +328,21 @@ where
T: Config,
C: OfflineClientT<T>,
{
/// Create a [`SubmittableExtrinsic`] from some already-signed and prepared
/// extrinsic bytes, and some client (anything implementing [`OfflineClientT`]
/// or [`OnlineClientT`]).
///
/// Prefer to use [`TxClient`] to create and sign extrinsics. This is simply
/// exposed in case you want to skip this process and submit something you've
/// already created.
pub fn from_bytes(client: C, tx_bytes: Vec<u8>) -> Self {
Self {
client,
encoded: Encoded(tx_bytes),
marker: std::marker::PhantomData,
}
}

/// Returns the SCALE encoded extrinsic bytes.
pub fn encoded(&self) -> &[u8] {
&self.encoded.0
Expand Down
50 changes: 22 additions & 28 deletions subxt/src/tx/tx_payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,31 @@ use std::borrow::Cow;
/// This represents a transaction payload that can be submitted
/// to a node.
pub trait TxPayload {
/// The name of the pallet that the call lives under.
fn pallet_name(&self) -> &str;

/// The name of the call.
fn call_name(&self) -> &str;

/// Encode call data to the provided output.
fn encode_call_data(
&self,
metadata: &Metadata,
out: &mut Vec<u8>,
) -> Result<(), Error>;

/// An optional validation hash that can be provided
/// to verify that the shape of the call on the node
/// aligns with our expectations.
fn validation_hash(&self) -> Option<[u8; 32]> {
/// Returns the details needed to validate the call, which
/// include a statically generated hash, the pallet name,
/// and the call name.
fn validation_details(&self) -> Option<ValidationDetails<'_>> {
None
}
}

pub struct ValidationDetails<'a> {
/// The pallet name.
pub pallet_name: &'a str,
/// The call name.
pub call_name: &'a str,
/// A hash (this is generated at compile time in our codegen)
/// to compare against the runtime code.
pub hash: [u8; 32],
}

/// This represents a statically generated transaction payload.
pub struct StaticTxPayload<CallData> {
pallet_name: &'static str,
Expand Down Expand Up @@ -74,14 +78,6 @@ impl<CallData> StaticTxPayload<CallData> {
}

impl<CallData: Encode> TxPayload for StaticTxPayload<CallData> {
fn pallet_name(&self) -> &str {
self.pallet_name
}

fn call_name(&self) -> &str {
self.call_name
}

fn encode_call_data(
&self,
metadata: &Metadata,
Expand All @@ -97,8 +93,14 @@ impl<CallData: Encode> TxPayload for StaticTxPayload<CallData> {
Ok(())
}

fn validation_hash(&self) -> Option<[u8; 32]> {
self.validation_hash
fn validation_details(&self) -> Option<ValidationDetails<'_>> {
self.validation_hash.map(|hash| {
ValidationDetails {
pallet_name: self.pallet_name,
call_name: self.call_name,
hash,
}
})
}
}

Expand All @@ -123,14 +125,6 @@ pub fn dynamic<'a>(
}

impl<'a> TxPayload for DynamicTxPayload<'a> {
fn pallet_name(&self) -> &str {
&self.pallet_name
}

fn call_name(&self) -> &str {
&self.call_name
}

fn encode_call_data(
&self,
metadata: &Metadata,
Expand Down

0 comments on commit 5ff8493

Please sign in to comment.