diff --git a/testing/integration-tests/src/full_client/blocks/mod.rs b/testing/integration-tests/src/full_client/blocks/mod.rs index f513d9a738..7df2cabfdd 100644 --- a/testing/integration-tests/src/full_client/blocks/mod.rs +++ b/testing/integration-tests/src/full_client/blocks/mod.rs @@ -2,13 +2,15 @@ // This file is dual-licensed as Apache-2.0 or GPL-3.0. // see LICENSE for license details. -use crate::{test_context, utils::node_runtime}; +use crate::test_context; use codec::{Compact, Encode}; use futures::StreamExt; #[cfg(lightclient)] use subxt::client::OnlineClientT; +#[cfg(fullclient)] +use crate::utils::node_runtime; #[cfg(fullclient)] use subxt::config::signed_extensions::{ChargeAssetTxPayment, CheckMortality, CheckNonce}; #[cfg(fullclient)] @@ -17,9 +19,10 @@ use subxt::config::DefaultExtrinsicParamsBuilder; use subxt::config::SubstrateConfig; #[cfg(fullclient)] use subxt::utils::Era; +#[cfg(fullclient)] +use subxt_signer::sr25519::dev; use subxt_metadata::Metadata; -use subxt_signer::sr25519::dev; #[cfg(fullclient)] #[tokio::test] diff --git a/testing/integration-tests/src/full_client/client/mod.rs b/testing/integration-tests/src/full_client/client/mod.rs index 74365166f8..49c049bf48 100644 --- a/testing/integration-tests/src/full_client/client/mod.rs +++ b/testing/integration-tests/src/full_client/client/mod.rs @@ -3,7 +3,7 @@ // see LICENSE for license details. use crate::{ - test_context, + submit_tx_wait_for_finalized_success, test_context, utils::{node_runtime, wait_for_blocks}, }; use codec::{Decode, Encode}; @@ -137,11 +137,7 @@ async fn transaction_validation() { .await .expect("validation failed"); - signed_extrinsic - .submit_and_watch() - .await - .unwrap() - .wait_for_finalized_success() + submit_tx_wait_for_finalized_success(&signed_extrinsic) .await .unwrap(); } @@ -204,11 +200,7 @@ async fn external_signing() { .sign_with_address_and_signature(&alice.public_key().into(), &signature.into()); // And now submit it. - extrinsic - .submit_and_watch() - .await - .unwrap() - .wait_for_finalized_success() + submit_tx_wait_for_finalized_success(&extrinsic) .await .unwrap(); } @@ -258,12 +250,13 @@ async fn decode_a_module_error() { // "unknown" module error from the assets pallet. let freeze_unknown_asset = node_runtime::tx().assets().freeze(1, alice_addr); - let err = api + let signed_extrinsic = api .tx() - .sign_and_submit_then_watch_default(&freeze_unknown_asset, &alice) + .create_signed(&freeze_unknown_asset, &alice, Default::default()) .await - .unwrap() - .wait_for_finalized_success() + .unwrap(); + + let err = submit_tx_wait_for_finalized_success(&signed_extrinsic) .await .expect_err("an 'unknown asset' error"); diff --git a/testing/integration-tests/src/full_client/frame/balances.rs b/testing/integration-tests/src/full_client/frame/balances.rs index 0fb1b02cac..73ea7b8261 100644 --- a/testing/integration-tests/src/full_client/frame/balances.rs +++ b/testing/integration-tests/src/full_client/frame/balances.rs @@ -4,7 +4,7 @@ use crate::{ node_runtime::{self, balances, runtime_types, system}, - test_context, + submit_tx_wait_for_finalized_success, test_context, }; use codec::Decode; use subxt::{ @@ -48,12 +48,12 @@ async fn tx_basic_transfer() -> Result<(), subxt::Error> { .balances() .transfer_allow_death(bob_address, 10_000); - let events = api + let signed_extrinsic = api .tx() - .sign_and_submit_then_watch_default(&tx, &alice) - .await? - .wait_for_finalized_success() + .create_signed(&tx, &alice, Default::default()) .await?; + let events = submit_tx_wait_for_finalized_success(&signed_extrinsic).await?; + let event = events .find_first::() .expect("Failed to decode balances::events::Transfer") @@ -235,11 +235,12 @@ async fn multiple_sequential_transfers_work() -> Result<(), subxt::Error> { .balances() .transfer_allow_death(bob_address.clone(), 10_000); for _ in 0..3 { - api.tx() - .sign_and_submit_then_watch_default(&tx, &alice) - .await? - .wait_for_finalized_success() + let signed_extrinsic = api + .tx() + .create_signed(&tx, &alice, Default::default()) .await?; + + submit_tx_wait_for_finalized_success(&signed_extrinsic).await?; } let bob_post = api @@ -282,10 +283,11 @@ async fn storage_balance_lock() -> Result<(), subxt::Error> { runtime_types::pallet_staking::RewardDestination::Stash, ); - api.tx() - .sign_and_submit_then_watch_default(&tx, &bob_signer) - .await? - .wait_for_finalized_success() + let signed_extrinsic = api + .tx() + .create_signed(&tx, &bob_signer, Default::default()) + .await?; + submit_tx_wait_for_finalized_success(&signed_extrinsic) .await? .find_first::()? .expect("No ExtrinsicSuccess Event found"); @@ -327,23 +329,24 @@ async fn transfer_error() { .balances() .transfer_allow_death(alice_addr, 100_000_000_000_000_000); - api.tx() - .sign_and_submit_then_watch_default(&to_bob_tx, &alice) + let signed_extrinsic = api + .tx() + .create_signed(&to_bob_tx, &alice, Default::default()) .await - .unwrap() - .wait_for_finalized_success() + .unwrap(); + submit_tx_wait_for_finalized_success(&signed_extrinsic) .await .unwrap(); // When we try giving all of the funds back, Bob doesn't have // anything left to pay transfer fees, so we hit an error. - let res = api + let signed_extrinsic = api .tx() - .sign_and_submit_then_watch_default(&to_alice_tx, &bob) + .create_signed(&to_alice_tx, &bob, Default::default()) .await - .unwrap() - .wait_for_finalized_success() - .await; + .unwrap(); + + let res = submit_tx_wait_for_finalized_success(&signed_extrinsic).await; assert!( matches!( @@ -367,12 +370,13 @@ async fn transfer_implicit_subscription() { .balances() .transfer_allow_death(bob.clone().into(), 10_000); - let event = api + let signed_extrinsic = api .tx() - .sign_and_submit_then_watch_default(&to_bob_tx, &alice) + .create_signed(&to_bob_tx, &alice, Default::default()) .await - .unwrap() - .wait_for_finalized_success() + .unwrap(); + + let event = submit_tx_wait_for_finalized_success(&signed_extrinsic) .await .unwrap() .find_first::() diff --git a/testing/integration-tests/src/full_client/frame/contracts.rs b/testing/integration-tests/src/full_client/frame/contracts.rs index 60039be1d7..c6ee58374e 100644 --- a/testing/integration-tests/src/full_client/frame/contracts.rs +++ b/testing/integration-tests/src/full_client/frame/contracts.rs @@ -9,7 +9,7 @@ use crate::{ runtime_types::{pallet_contracts::wasm::Determinism, sp_weights::weight_v2::Weight}, system, }, - test_context, TestClient, TestConfig, TestContext, + submit_tx_wait_for_finalized_success, test_context, TestClient, TestConfig, TestContext, }; use subxt::ext::futures::StreamExt; use subxt::{tx::TxProgress, utils::MultiAddress, Config, Error}; @@ -54,13 +54,12 @@ impl ContractsTestContext { .contracts() .upload_code(code, None, Determinism::Enforced); - let events = self + let signed_extrinsic = self .client() .tx() - .sign_and_submit_then_watch_default(&upload_tx, &self.signer) - .await? - .wait_for_finalized_success() + .create_signed(&upload_tx, &self.signer, Default::default()) .await?; + let events = submit_tx_wait_for_finalized_success(&signed_extrinsic).await?; let code_stored = events .find_first::()? @@ -84,13 +83,12 @@ impl ContractsTestContext { vec![], // salt ); - let events = self + let signed_extrinsic = self .client() .tx() - .sign_and_submit_then_watch_default(&instantiate_tx, &self.signer) - .await? - .wait_for_finalized_success() + .create_signed(&instantiate_tx, &self.signer, Default::default()) .await?; + let events = submit_tx_wait_for_finalized_success(&signed_extrinsic).await?; let code_stored = events .find_first::()? @@ -127,13 +125,12 @@ impl ContractsTestContext { salt, ); - let result = self + let signed_extrinsic = self .client() .tx() - .sign_and_submit_then_watch_default(&instantiate_tx, &self.signer) - .await? - .wait_for_finalized_success() + .create_signed(&instantiate_tx, &self.signer, Default::default()) .await?; + let result = submit_tx_wait_for_finalized_success(&signed_extrinsic).await?; tracing::info!("Instantiate result: {:?}", result); let instantiated = result diff --git a/testing/integration-tests/src/full_client/frame/staking.rs b/testing/integration-tests/src/full_client/frame/staking.rs index 7d285faa8a..91eba84f43 100644 --- a/testing/integration-tests/src/full_client/frame/staking.rs +++ b/testing/integration-tests/src/full_client/frame/staking.rs @@ -11,7 +11,7 @@ use crate::{ }, staking, }, - test_context, + submit_tx_wait_for_finalized_success, test_context, }; use assert_matches::assert_matches; use subxt::error::{DispatchError, Error}; @@ -45,11 +45,12 @@ async fn validate_with_stash_account() { .staking() .validate(default_validator_prefs()); - api.tx() - .sign_and_submit_then_watch_default(&tx, &alice_stash) + let signed_extrinsic = api + .tx() + .create_signed(&tx, &alice_stash, Default::default()) .await - .unwrap() - .wait_for_finalized_success() + .unwrap(); + submit_tx_wait_for_finalized_success(&signed_extrinsic) .await .expect("should be successful"); } @@ -65,12 +66,12 @@ async fn validate_not_possible_for_controller_account() -> Result<(), Error> { .staking() .validate(default_validator_prefs()); - let announce_validator = api + let signed_extrinsic = api .tx() - .sign_and_submit_then_watch_default(&tx, &alice) - .await? - .wait_for_finalized_success() - .await; + .create_signed(&tx, &alice, Default::default()) + .await?; + let announce_validator = submit_tx_wait_for_finalized_success(&signed_extrinsic).await; + assert_matches!(announce_validator, Err(Error::Runtime(DispatchError::Module(err))) => { let details = err.details().unwrap(); assert_eq!(details.pallet.name(), "Staking"); @@ -91,11 +92,12 @@ async fn nominate_with_stash_account() { .staking() .nominate(vec![bob.public_key().to_address()]); - api.tx() - .sign_and_submit_then_watch_default(&tx, &alice_stash) + let signed_extrinsic = api + .tx() + .create_signed(&tx, &alice_stash, Default::default()) .await - .unwrap() - .wait_for_finalized_success() + .unwrap(); + submit_tx_wait_for_finalized_success(&signed_extrinsic) .await .expect("should be successful"); } @@ -112,13 +114,12 @@ async fn nominate_not_possible_for_controller_account() -> Result<(), Error> { .staking() .nominate(vec![bob.public_key().to_address()]); - let nomination = api + let signed_extrinsic = api .tx() - .sign_and_submit_then_watch_default(&tx, &alice) + .create_signed(&tx, &alice, Default::default()) .await - .unwrap() - .wait_for_finalized_success() - .await; + .unwrap(); + let nomination = submit_tx_wait_for_finalized_success(&signed_extrinsic).await; assert_matches!(nomination, Err(Error::Runtime(DispatchError::Module(err))) => { let details = err.details().unwrap(); @@ -141,11 +142,12 @@ async fn chill_works_for_stash_only() -> Result<(), Error> { let nominate_tx = node_runtime::tx() .staking() .nominate(vec![bob_stash.public_key().to_address()]); - api.tx() - .sign_and_submit_then_watch_default(&nominate_tx, &alice_stash) - .await? - .wait_for_finalized_success() + + let signed_extrinsic = api + .tx() + .create_signed(&nominate_tx, &alice_stash, Default::default()) .await?; + submit_tx_wait_for_finalized_success(&signed_extrinsic).await?; let ledger_addr = node_runtime::storage() .staking() @@ -161,12 +163,11 @@ async fn chill_works_for_stash_only() -> Result<(), Error> { let chill_tx = node_runtime::tx().staking().chill(); - let chill = api + let signed_extrinsic = api .tx() - .sign_and_submit_then_watch_default(&chill_tx, &alice) - .await? - .wait_for_finalized_success() - .await; + .create_signed(&chill_tx, &alice, Default::default()) + .await?; + let chill = submit_tx_wait_for_finalized_success(&signed_extrinsic).await; assert_matches!(chill, Err(Error::Runtime(DispatchError::Module(err))) => { let details = err.details().unwrap(); @@ -174,13 +175,14 @@ async fn chill_works_for_stash_only() -> Result<(), Error> { assert_eq!(&details.variant.name, "NotController"); }); - let is_chilled = api + let signed_extrinsic = api .tx() - .sign_and_submit_then_watch_default(&chill_tx, &alice_stash) - .await? - .wait_for_finalized_success() + .create_signed(&chill_tx, &alice_stash, Default::default()) + .await?; + let is_chilled = submit_tx_wait_for_finalized_success(&signed_extrinsic) .await? .has::()?; + assert!(is_chilled); Ok(()) @@ -197,21 +199,19 @@ async fn tx_bond() -> Result<(), Error> { .staking() .bond(100_000_000_000_000, RewardDestination::Stash); - let bond = api + let signed_extrinsic = api .tx() - .sign_and_submit_then_watch_default(&bond_tx, &alice) - .await? - .wait_for_finalized_success() - .await; + .create_signed(&bond_tx, &alice, Default::default()) + .await?; + let bond = submit_tx_wait_for_finalized_success(&signed_extrinsic).await; assert!(bond.is_ok()); - let bond_again = api + let signed_extrinsic = api .tx() - .sign_and_submit_then_watch_default(&bond_tx, &alice) - .await? - .wait_for_finalized_success() - .await; + .create_signed(&bond_tx, &alice, Default::default()) + .await?; + let bond_again = submit_tx_wait_for_finalized_success(&signed_extrinsic).await; assert_matches!(bond_again, Err(Error::Runtime(DispatchError::Module(err))) => { let details = err.details().unwrap(); diff --git a/testing/integration-tests/src/full_client/frame/sudo.rs b/testing/integration-tests/src/full_client/frame/sudo.rs index fad808d563..4d34ee862d 100644 --- a/testing/integration-tests/src/full_client/frame/sudo.rs +++ b/testing/integration-tests/src/full_client/frame/sudo.rs @@ -8,7 +8,7 @@ use crate::{ runtime_types::{self, sp_weights::weight_v2::Weight}, sudo, }, - test_context, + submit_tx_wait_for_finalized_success, test_context, }; use subxt_signer::sr25519::dev; @@ -29,11 +29,12 @@ async fn test_sudo() -> Result<(), subxt::Error> { }); let tx = node_runtime::tx().sudo().sudo(call); - let found_event = api + let signed_extrinsic = api .tx() - .sign_and_submit_then_watch_default(&tx, &alice) - .await? - .wait_for_finalized_success() + .create_signed(&tx, &alice, Default::default()) + .await?; + + let found_event = submit_tx_wait_for_finalized_success(&signed_extrinsic) .await? .has::()?; @@ -61,11 +62,12 @@ async fn test_sudo_unchecked_weight() -> Result<(), subxt::Error> { }, ); - let found_event = api + let signed_extrinsic = api .tx() - .sign_and_submit_then_watch_default(&tx, &alice) - .await? - .wait_for_finalized_success() + .create_signed(&tx, &alice, Default::default()) + .await?; + + let found_event = submit_tx_wait_for_finalized_success(&signed_extrinsic) .await? .has::()?; diff --git a/testing/integration-tests/src/full_client/frame/system.rs b/testing/integration-tests/src/full_client/frame/system.rs index 1b3823cead..bb966b1293 100644 --- a/testing/integration-tests/src/full_client/frame/system.rs +++ b/testing/integration-tests/src/full_client/frame/system.rs @@ -4,7 +4,7 @@ use crate::{ node_runtime::{self, system}, - test_context, + submit_tx_wait_for_finalized_success, test_context, }; use assert_matches::assert_matches; use subxt_signer::sr25519::dev; @@ -42,11 +42,12 @@ async fn tx_remark_with_event() -> Result<(), subxt::Error> { .system() .remark_with_event(b"remarkable".to_vec()); - let found_event = api + let signed_extrinsic = api .tx() - .sign_and_submit_then_watch_default(&tx, &alice) - .await? - .wait_for_finalized_success() + .create_signed(&tx, &alice, Default::default()) + .await?; + + let found_event = submit_tx_wait_for_finalized_success(&signed_extrinsic) .await? .has::()?; diff --git a/testing/integration-tests/src/full_client/runtime_api/mod.rs b/testing/integration-tests/src/full_client/runtime_api/mod.rs index 2a637f9aff..290c3b1534 100644 --- a/testing/integration-tests/src/full_client/runtime_api/mod.rs +++ b/testing/integration-tests/src/full_client/runtime_api/mod.rs @@ -2,7 +2,7 @@ // This file is dual-licensed as Apache-2.0 or GPL-3.0. // see LICENSE for license details. -use crate::{node_runtime, test_context}; +use crate::{node_runtime, submit_tx_wait_for_finalized_success, test_context}; use codec::Encode; use subxt::utils::AccountId32; use subxt_signer::sr25519::dev; @@ -29,11 +29,11 @@ async fn account_nonce() -> Result<(), subxt::Error> { // Do some transaction to bump the Alice nonce to 1: let remark_tx = node_runtime::tx().system().remark(vec![1, 2, 3, 4, 5]); - api.tx() - .sign_and_submit_then_watch_default(&remark_tx, &alice) - .await? - .wait_for_finalized_success() + let signed_extrinsic = api + .tx() + .create_signed(&remark_tx, &alice, Default::default()) .await?; + submit_tx_wait_for_finalized_success(&signed_extrinsic).await?; let runtime_api_call = node_runtime::apis() .account_nonce_api() diff --git a/testing/integration-tests/src/full_client/storage/mod.rs b/testing/integration-tests/src/full_client/storage/mod.rs index af5b85f3a3..7ad44b8175 100644 --- a/testing/integration-tests/src/full_client/storage/mod.rs +++ b/testing/integration-tests/src/full_client/storage/mod.rs @@ -3,7 +3,10 @@ // see LICENSE for license details. use crate::{node_runtime, test_context, utils::wait_for_blocks}; + +#[cfg(fullclient)] use subxt::utils::AccountId32; +#[cfg(fullclient)] use subxt_signer::sr25519::dev; #[tokio::test] @@ -27,6 +30,7 @@ async fn storage_plain_lookup() -> Result<(), subxt::Error> { Ok(()) } +#[cfg(fullclient)] #[tokio::test] async fn storage_map_lookup() -> Result<(), subxt::Error> { let ctx = test_context().await; @@ -60,6 +64,7 @@ async fn storage_map_lookup() -> Result<(), subxt::Error> { // Here we create a key that looks a bit like a StorageNMap key, but should in fact be // treated as a StorageKey (ie we should hash both values together with one hasher, rather // than hash both values separately, or ignore the second value). +#[cfg(fullclient)] #[tokio::test] async fn storage_n_mapish_key_is_properly_created() -> Result<(), subxt::Error> { use codec::Encode; diff --git a/testing/integration-tests/src/utils/mod.rs b/testing/integration-tests/src/utils/mod.rs index 08a3111da8..ee668886c0 100644 --- a/testing/integration-tests/src/utils/mod.rs +++ b/testing/integration-tests/src/utils/mod.rs @@ -4,8 +4,10 @@ mod context; mod node_proc; +mod tx_retries; mod wait_for_blocks; pub use context::*; pub use node_proc::TestNodeProcess; +pub use tx_retries::*; pub use wait_for_blocks::wait_for_blocks; diff --git a/testing/integration-tests/src/utils/tx_retries.rs b/testing/integration-tests/src/utils/tx_retries.rs new file mode 100644 index 0000000000..800222a455 --- /dev/null +++ b/testing/integration-tests/src/utils/tx_retries.rs @@ -0,0 +1,40 @@ +// Copyright 2019-2024 Parity Technologies (UK) Ltd. +// This file is dual-licensed as Apache-2.0 or GPL-3.0. +// see LICENSE for license details. + +use subxt::client::OnlineClientT; +use subxt::tx::SubmittableExtrinsic; +use subxt::Config; + +pub async fn submit_tx_wait_for_finalized_success( + signed_extrinsic: &SubmittableExtrinsic, +) -> Result, subxt::Error> +where + T: Config, + C: OnlineClientT, +{ + let submit = || async { + signed_extrinsic + .submit_and_watch() + .await + .unwrap() + .wait_for_finalized_success() + .await + }; + + #[cfg(lightclient)] + for _ in 0..2 { + let result = submit().await; + + match result { + Ok(tx_in_block) => return Ok(tx_in_block), + Err(subxt::Error::Transaction(subxt::error::TransactionError::Dropped(_))) => { + // Retry if the transaction was dropped. + tokio::time::sleep(std::time::Duration::from_secs(5)).await; + } + Err(other) => return Err(other), + } + } + + submit().await +}