TransactionInvalidationTracker (#1544)

* TransactionInvalidationTracker

* TransacitonInvalidationTracker -> TransactionTracker

* change sign_transaction method

* clippy and spelling

* removed comment

* more transactiontracker tests

* stalls_when_transaction_tracker_returns_error

* remove test code

* remove "impl TransactionTracker for ()"

* enum TrackedTransactionStatus

* test TransactionTracker in on_transaction_status

* do_wait
This commit is contained in:
Svyatoslav Nikolsky
2022-09-14 17:30:57 +03:00
committed by Bastian Köcher
parent 58fe2749d2
commit 70d6e91f20
8 changed files with 514 additions and 145 deletions
@@ -26,10 +26,8 @@ use polkadot_runtime_common::{
paras_registrar::Call as ParaRegistrarCall, slots::Call as ParaSlotsCall,
};
use polkadot_runtime_parachains::paras::ParaLifecycle;
use relay_substrate_client::{
AccountIdOf, CallOf, Chain, Client, HashOf, SignParam, Subscription, TransactionStatusOf,
UnsignedTransaction,
};
use relay_substrate_client::{AccountIdOf, CallOf, Chain, Client, SignParam, UnsignedTransaction};
use relay_utils::{TrackedTransactionStatus, TransactionTracker};
use rialto_runtime::SudoCall;
use sp_core::{
storage::{well_known_keys::CODE, StorageKey},
@@ -116,26 +114,30 @@ impl RegisterParachain {
ParaRegistrarCall::reserve {}.into();
let reserve_parachain_signer = relay_sign.clone();
let (spec_version, transaction_version) = relay_client.simple_runtime_version().await?;
wait_until_transaction_is_finalized::<Relaychain>(
relay_client
.submit_and_watch_signed_extrinsic(
relay_sudo_account.clone(),
SignParam::<Relaychain> {
spec_version,
transaction_version,
genesis_hash: relay_genesis_hash,
signer: reserve_parachain_signer,
},
move |_, transaction_nonce| {
Ok(UnsignedTransaction::new(
reserve_parachain_id_call.into(),
transaction_nonce,
))
},
)
.await?,
)
.await?;
let reserve_result = relay_client
.submit_and_watch_signed_extrinsic(
relay_sudo_account.clone(),
SignParam::<Relaychain> {
spec_version,
transaction_version,
genesis_hash: relay_genesis_hash,
signer: reserve_parachain_signer,
},
move |_, transaction_nonce| {
Ok(UnsignedTransaction::new(
reserve_parachain_id_call.into(),
transaction_nonce,
))
},
)
.await?
.wait()
.await;
if reserve_result == TrackedTransactionStatus::Lost {
return Err(anyhow::format_err!(
"Failed to finalize `reserve-parachain-id` transaction"
))
}
log::info!(target: "bridge", "Reserved parachain id: {:?}", para_id);
// step 2: register parathread
@@ -161,26 +163,30 @@ impl RegisterParachain {
}
.into();
let register_parathread_signer = relay_sign.clone();
wait_until_transaction_is_finalized::<Relaychain>(
relay_client
.submit_and_watch_signed_extrinsic(
relay_sudo_account.clone(),
SignParam::<Relaychain> {
spec_version,
transaction_version,
genesis_hash: relay_genesis_hash,
signer: register_parathread_signer,
},
move |_, transaction_nonce| {
Ok(UnsignedTransaction::new(
register_parathread_call.into(),
transaction_nonce,
))
},
)
.await?,
)
.await?;
let register_result = relay_client
.submit_and_watch_signed_extrinsic(
relay_sudo_account.clone(),
SignParam::<Relaychain> {
spec_version,
transaction_version,
genesis_hash: relay_genesis_hash,
signer: register_parathread_signer,
},
move |_, transaction_nonce| {
Ok(UnsignedTransaction::new(
register_parathread_call.into(),
transaction_nonce,
))
},
)
.await?
.wait()
.await;
if register_result == TrackedTransactionStatus::Lost {
return Err(anyhow::format_err!(
"Failed to finalize `register-parathread` transaction"
))
}
log::info!(target: "bridge", "Registered parachain: {:?}. Waiting for onboarding", para_id);
// wait until parathread is onboarded
@@ -256,46 +262,6 @@ impl RegisterParachain {
}
}
/// Wait until transaction is included into finalized block.
///
/// Returns the hash of the finalized block with transaction.
pub(crate) async fn wait_until_transaction_is_finalized<C: Chain>(
subscription: Subscription<TransactionStatusOf<C>>,
) -> anyhow::Result<HashOf<C>> {
loop {
let transaction_status = subscription.next().await?;
match transaction_status {
Some(TransactionStatusOf::<C>::FinalityTimeout(_)) |
Some(TransactionStatusOf::<C>::Usurped(_)) |
Some(TransactionStatusOf::<C>::Dropped) |
Some(TransactionStatusOf::<C>::Invalid) |
None =>
return Err(anyhow::format_err!(
"We've been waiting for finalization of {} transaction, but it now has the {:?} status",
C::NAME,
transaction_status,
)),
Some(TransactionStatusOf::<C>::Finalized(block_hash)) => {
log::trace!(
target: "bridge",
"{} transaction has been finalized at block {}",
C::NAME,
block_hash,
);
return Ok(block_hash)
},
_ => {
log::trace!(
target: "bridge",
"Received intermediate status of {} transaction: {:?}",
C::NAME,
transaction_status,
);
},
}
}
}
/// Wait until parachain state is changed.
async fn wait_para_state<Relaychain: Chain>(
relay_client: &Client<Relaychain>,