Skip to content

Commit

Permalink
Final check before transaction submit (#2351)
Browse files Browse the repository at this point in the history
* final check before transaction submit

* pass pre-encoded transaction to validate
  • Loading branch information
svyatonik authored and bkontur committed May 20, 2024
1 parent 7a394d8 commit ed75f80
Showing 1 changed file with 33 additions and 7 deletions.
40 changes: 33 additions & 7 deletions bridges/relays/client-substrate/src/client/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,15 @@ struct ClientData {
client: Arc<WsClient>,
}

/// Already encoded value.
struct PreEncoded(Vec<u8>);

impl Encode for PreEncoded {
fn encode(&self) -> Vec<u8> {
self.0.clone()
}
}

impl<C: Chain> std::fmt::Debug for RpcClient<C> {
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
fmt.write_fmt(format_args!("RpcClient<{}>", C::NAME))
Expand Down Expand Up @@ -430,6 +439,14 @@ impl<C: Chain> Client<C> for RpcClient<C> {
}

async fn submit_unsigned_extrinsic(&self, transaction: Bytes) -> Result<HashOf<C>> {
// one last check that the transaction is valid. Most of checks happen in the relay loop and
// it is the "final" check before submission.
let best_header_hash = self.best_header_hash().await?;
self.validate_transaction(best_header_hash, PreEncoded(transaction.0.clone()))
.await
.map_err(|e| Error::failed_to_submit_transaction::<C>(e))?
.map_err(|e| Error::failed_to_submit_transaction::<C>(Error::TransactionInvalid(e)))?;

self.jsonrpsee_execute(move |client| async move {
let tx_hash = SubstrateAuthorClient::<C>::submit_extrinsic(&*client, transaction)
.await
Expand Down Expand Up @@ -489,14 +506,23 @@ impl<C: Chain> Client<C> for RpcClient<C> {
let transaction_nonce = self.next_account_index(signer.public().into()).await?;
let best_header = self.best_header().await?;
let best_header_id = best_header.id();

let extrinsic = prepare_extrinsic(best_header_id, transaction_nonce)?;
let stall_timeout = transaction_stall_timeout(
extrinsic.era.mortality_period(),
C::AVERAGE_BLOCK_INTERVAL,
STALL_TIMEOUT,
);
let signed_extrinsic = C::sign_transaction(signing_data, extrinsic)?.encode();

// one last check that the transaction is valid. Most of checks happen in the relay loop and
// it is the "final" check before submission.
self.validate_transaction(best_header_id.hash(), PreEncoded(signed_extrinsic.clone()))
.await
.map_err(|e| Error::failed_to_submit_transaction::<C>(e))?
.map_err(|e| Error::failed_to_submit_transaction::<C>(Error::TransactionInvalid(e)))?;

self.jsonrpsee_execute(move |client| async move {
let extrinsic = prepare_extrinsic(best_header_id, transaction_nonce)?;
let stall_timeout = transaction_stall_timeout(
extrinsic.era.mortality_period(),
C::AVERAGE_BLOCK_INTERVAL,
STALL_TIMEOUT,
);
let signed_extrinsic = C::sign_transaction(signing_data, extrinsic)?.encode();
let tx_hash = C::Hasher::hash(&signed_extrinsic);
let subscription: jsonrpsee::core::client::Subscription<_> =
SubstrateAuthorClient::<C>::submit_and_watch_extrinsic(
Expand Down

0 comments on commit ed75f80

Please sign in to comment.