Extract unsigned tx from the SignParam structure (#1561)

* change sign_transaction method

* clippy

* rustup update && clippy

* remove redudnant clone
This commit is contained in:
Svyatoslav Nikolsky
2022-08-30 13:58:37 +03:00
committed by Bastian Köcher
parent effe0f11c8
commit f35b4f4897
29 changed files with 434 additions and 402 deletions
+19 -9
View File
@@ -15,7 +15,9 @@
// along with Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>.
use bp_messages::MessageNonce;
use bp_runtime::{Chain as ChainBase, EncodedOrDecodedCall, HashOf, TransactionEraOf};
use bp_runtime::{
Chain as ChainBase, EncodedOrDecodedCall, HashOf, TransactionEra, TransactionEraOf,
};
use codec::{Codec, Encode};
use frame_support::weights::{Weight, WeightToFeePolynomial};
use jsonrpsee::core::{DeserializeOwned, Serialize};
@@ -158,12 +160,14 @@ pub struct UnsignedTransaction<C: Chain> {
pub nonce: C::Index,
/// Tip included into transaction.
pub tip: C::Balance,
/// Transaction era used by the chain.
pub era: TransactionEraOf<C>,
}
impl<C: Chain> UnsignedTransaction<C> {
/// Create new unsigned transaction with given call, nonce and zero tip.
/// Create new unsigned transaction with given call, nonce, era and zero tip.
pub fn new(call: EncodedOrDecodedCall<C::Call>, nonce: C::Index) -> Self {
Self { call, nonce, tip: Zero::zero() }
Self { call, nonce, era: TransactionEra::Immortal, tip: Zero::zero() }
}
/// Set transaction tip.
@@ -172,13 +176,20 @@ impl<C: Chain> UnsignedTransaction<C> {
self.tip = tip;
self
}
/// Set transaction era.
#[must_use]
pub fn era(mut self, era: TransactionEraOf<C>) -> Self {
self.era = era;
self
}
}
/// Account key pair used by transactions signing scheme.
pub type AccountKeyPairOf<S> = <S as TransactionSignScheme>::AccountKeyPair;
/// Substrate-based chain transactions signing scheme.
pub trait TransactionSignScheme {
pub trait TransactionSignScheme: 'static {
/// Chain that this scheme is to be used.
type Chain: Chain;
/// Type of key pairs used to sign transactions.
@@ -187,7 +198,10 @@ pub trait TransactionSignScheme {
type SignedTransaction: Clone + Debug + Codec + Send + 'static;
/// Create transaction for given runtime call, signed by given account.
fn sign_transaction(param: SignParam<Self>) -> Result<Self::SignedTransaction, crate::Error>
fn sign_transaction(
param: SignParam<Self>,
unsigned: UnsignedTransaction<Self::Chain>,
) -> Result<Self::SignedTransaction, crate::Error>
where
Self: Sized;
@@ -213,10 +227,6 @@ pub struct SignParam<T: TransactionSignScheme> {
pub genesis_hash: <T::Chain as ChainBase>::Hash,
/// Signer account
pub signer: T::AccountKeyPair,
/// Transaction era used by the chain.
pub era: TransactionEraOf<T::Chain>,
/// Transaction before it is signed.
pub unsigned: UnsignedTransaction<T::Chain>,
}
impl<Block: BlockT> BlockWithJustification<Block::Header> for SignedBlock<Block> {
+34 -20
View File
@@ -17,13 +17,14 @@
//! Substrate node client.
use crate::{
chain::{Chain, ChainWithBalances, TransactionStatusOf},
chain::{Chain, ChainWithBalances},
rpc::{
SubstrateAuthorClient, SubstrateChainClient, SubstrateFrameSystemClient,
SubstrateGrandpaClient, SubstrateStateClient, SubstrateSystemClient,
SubstrateTransactionPaymentClient,
},
ConnectionParams, Error, HashOf, HeaderIdOf, Result,
ConnectionParams, Error, HashOf, HeaderIdOf, Result, SignParam, TransactionSignScheme,
TransactionStatusOf, UnsignedTransaction,
};
use async_std::sync::{Arc, Mutex};
@@ -403,10 +404,13 @@ impl<C: Chain> Client<C> {
/// if all client instances are clones of the same initial `Client`.
///
/// Note: The given transaction needs to be SCALE encoded beforehand.
pub async fn submit_signed_extrinsic(
pub async fn submit_signed_extrinsic<S: TransactionSignScheme<Chain = C> + 'static>(
&self,
extrinsic_signer: C::AccountId,
prepare_extrinsic: impl FnOnce(HeaderIdOf<C>, C::Index) -> Result<Bytes> + Send + 'static,
signing_data: SignParam<S>,
prepare_extrinsic: impl FnOnce(HeaderIdOf<C>, C::Index) -> Result<UnsignedTransaction<C>>
+ Send
+ 'static,
) -> Result<C::Hash> {
let _guard = self.submit_signed_extrinsic_lock.lock().await;
let transaction_nonce = self.next_account_index(extrinsic_signer).await?;
@@ -421,12 +425,14 @@ impl<C: Chain> Client<C> {
self.jsonrpsee_execute(move |client| async move {
let extrinsic = prepare_extrinsic(best_header_id, transaction_nonce)?;
let tx_hash = SubstrateAuthorClient::<C>::submit_extrinsic(&*client, extrinsic)
.await
.map_err(|e| {
log::error!(target: "bridge", "Failed to send transaction to {} node: {:?}", C::NAME, e);
e
})?;
let signed_extrinsic = S::sign_transaction(signing_data, extrinsic)?.encode();
let tx_hash =
SubstrateAuthorClient::<C>::submit_extrinsic(&*client, Bytes(signed_extrinsic))
.await
.map_err(|e| {
log::error!(target: "bridge", "Failed to send transaction to {} node: {:?}", C::NAME, e);
e
})?;
log::trace!(target: "bridge", "Sent transaction to {} node: {:?}", C::NAME, tx_hash);
Ok(tx_hash)
})
@@ -435,10 +441,15 @@ impl<C: Chain> Client<C> {
/// Does exactly the same as `submit_signed_extrinsic`, but keeps watching for extrinsic status
/// after submission.
pub async fn submit_and_watch_signed_extrinsic(
pub async fn submit_and_watch_signed_extrinsic<
S: TransactionSignScheme<Chain = C> + 'static,
>(
&self,
extrinsic_signer: C::AccountId,
prepare_extrinsic: impl FnOnce(HeaderIdOf<C>, C::Index) -> Result<Bytes> + Send + 'static,
signing_data: SignParam<S>,
prepare_extrinsic: impl FnOnce(HeaderIdOf<C>, C::Index) -> Result<UnsignedTransaction<C>>
+ Send
+ 'static,
) -> Result<Subscription<TransactionStatusOf<C>>> {
let _guard = self.submit_signed_extrinsic_lock.lock().await;
let transaction_nonce = self.next_account_index(extrinsic_signer).await?;
@@ -447,14 +458,17 @@ impl<C: Chain> Client<C> {
let subscription = self
.jsonrpsee_execute(move |client| async move {
let extrinsic = prepare_extrinsic(best_header_id, transaction_nonce)?;
let tx_hash = C::Hasher::hash(&extrinsic.0);
let subscription =
SubstrateAuthorClient::<C>::submit_and_watch_extrinsic(&*client, extrinsic)
.await
.map_err(|e| {
log::error!(target: "bridge", "Failed to send transaction to {} node: {:?}", C::NAME, e);
e
})?;
let signed_extrinsic = S::sign_transaction(signing_data, extrinsic)?.encode();
let tx_hash = C::Hasher::hash(&signed_extrinsic);
let subscription = SubstrateAuthorClient::<C>::submit_and_watch_extrinsic(
&*client,
Bytes(signed_extrinsic),
)
.await
.map_err(|e| {
log::error!(target: "bridge", "Failed to send transaction to {} node: {:?}", C::NAME, e);
e
})?;
log::trace!(target: "bridge", "Sent transaction to {} node: {:?}", C::NAME, tx_hash);
Ok(subscription)
})