Skip to content

Commit 5ff8493

Browse files
authored
Simplify the TxPayload trait a little (paritytech#638)
* 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
1 parent 0b2c31e commit 5ff8493

File tree

2 files changed

+50
-43
lines changed

2 files changed

+50
-43
lines changed

subxt/src/tx/tx_client.rs

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,14 @@ impl<T: Config, C: OfflineClientT<T>> TxClient<T, C> {
5757
where
5858
Call: TxPayload,
5959
{
60-
if let Some(actual_hash) = call.validation_hash() {
60+
if let Some(details) = call.validation_details() {
6161
let metadata = self.client.metadata();
6262
let expected_hash =
63-
metadata.call_hash(call.pallet_name(), call.call_name())?;
64-
if actual_hash != expected_hash {
63+
metadata.call_hash(details.pallet_name, details.call_name)?;
64+
if details.hash != expected_hash {
6565
return Err(crate::metadata::MetadataError::IncompatibleCallMetadata(
66-
call.pallet_name().into(),
67-
call.call_name().into(),
66+
details.pallet_name.into(),
67+
details.call_name.into(),
6868
)
6969
.into())
7070
}
@@ -114,11 +114,10 @@ impl<T: Config, C: OfflineClientT<T>> TxClient<T, C> {
114114
};
115115

116116
// Wrap in Encoded to ensure that any more "encode" calls leave it in the right state.
117-
Ok(SubmittableExtrinsic {
118-
client: self.client.clone(),
119-
encoded: Encoded(extrinsic),
120-
marker: std::marker::PhantomData,
121-
})
117+
Ok(SubmittableExtrinsic::from_bytes(
118+
self.client.clone(),
119+
extrinsic,
120+
))
122121
}
123122

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

203202
// Wrap in Encoded to ensure that any more "encode" calls leave it in the right state.
204203
// maybe we can just return the raw bytes..
205-
Ok(SubmittableExtrinsic {
206-
client: self.client.clone(),
207-
encoded: Encoded(extrinsic),
208-
marker: std::marker::PhantomData,
209-
})
204+
Ok(SubmittableExtrinsic::from_bytes(
205+
self.client.clone(),
206+
extrinsic,
207+
))
210208
}
211209
}
212210

@@ -330,6 +328,21 @@ where
330328
T: Config,
331329
C: OfflineClientT<T>,
332330
{
331+
/// Create a [`SubmittableExtrinsic`] from some already-signed and prepared
332+
/// extrinsic bytes, and some client (anything implementing [`OfflineClientT`]
333+
/// or [`OnlineClientT`]).
334+
///
335+
/// Prefer to use [`TxClient`] to create and sign extrinsics. This is simply
336+
/// exposed in case you want to skip this process and submit something you've
337+
/// already created.
338+
pub fn from_bytes(client: C, tx_bytes: Vec<u8>) -> Self {
339+
Self {
340+
client,
341+
encoded: Encoded(tx_bytes),
342+
marker: std::marker::PhantomData,
343+
}
344+
}
345+
333346
/// Returns the SCALE encoded extrinsic bytes.
334347
pub fn encoded(&self) -> &[u8] {
335348
&self.encoded.0

subxt/src/tx/tx_payload.rs

Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -19,27 +19,31 @@ use std::borrow::Cow;
1919
/// This represents a transaction payload that can be submitted
2020
/// to a node.
2121
pub trait TxPayload {
22-
/// The name of the pallet that the call lives under.
23-
fn pallet_name(&self) -> &str;
24-
25-
/// The name of the call.
26-
fn call_name(&self) -> &str;
27-
2822
/// Encode call data to the provided output.
2923
fn encode_call_data(
3024
&self,
3125
metadata: &Metadata,
3226
out: &mut Vec<u8>,
3327
) -> Result<(), Error>;
3428

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

37+
pub struct ValidationDetails<'a> {
38+
/// The pallet name.
39+
pub pallet_name: &'a str,
40+
/// The call name.
41+
pub call_name: &'a str,
42+
/// A hash (this is generated at compile time in our codegen)
43+
/// to compare against the runtime code.
44+
pub hash: [u8; 32],
45+
}
46+
4347
/// This represents a statically generated transaction payload.
4448
pub struct StaticTxPayload<CallData> {
4549
pallet_name: &'static str,
@@ -74,14 +78,6 @@ impl<CallData> StaticTxPayload<CallData> {
7478
}
7579

7680
impl<CallData: Encode> TxPayload for StaticTxPayload<CallData> {
77-
fn pallet_name(&self) -> &str {
78-
self.pallet_name
79-
}
80-
81-
fn call_name(&self) -> &str {
82-
self.call_name
83-
}
84-
8581
fn encode_call_data(
8682
&self,
8783
metadata: &Metadata,
@@ -97,8 +93,14 @@ impl<CallData: Encode> TxPayload for StaticTxPayload<CallData> {
9793
Ok(())
9894
}
9995

100-
fn validation_hash(&self) -> Option<[u8; 32]> {
101-
self.validation_hash
96+
fn validation_details(&self) -> Option<ValidationDetails<'_>> {
97+
self.validation_hash.map(|hash| {
98+
ValidationDetails {
99+
pallet_name: self.pallet_name,
100+
call_name: self.call_name,
101+
hash,
102+
}
103+
})
102104
}
103105
}
104106

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

125127
impl<'a> TxPayload for DynamicTxPayload<'a> {
126-
fn pallet_name(&self) -> &str {
127-
&self.pallet_name
128-
}
129-
130-
fn call_name(&self) -> &str {
131-
&self.call_name
132-
}
133-
134128
fn encode_call_data(
135129
&self,
136130
metadata: &Metadata,

0 commit comments

Comments
 (0)