diff --git a/crates/pallet-domains/src/lib.rs b/crates/pallet-domains/src/lib.rs index aab92ac09f..a4d48a7e29 100644 --- a/crates/pallet-domains/src/lib.rs +++ b/crates/pallet-domains/src/lib.rs @@ -699,7 +699,7 @@ mod pallet { #[pallet::storage] pub(super) type AccumulatedTreasuryFunds = StorageValue<_, BalanceOf, ValueQuery>; - /// Storage used to keep track of which consensus block the domain runtime upgrade happen. + /// Storage used to keep track of which consensus block each domain runtime upgrade happens in. #[pallet::storage] pub(super) type DomainRuntimeUpgradeRecords = StorageMap< _, @@ -709,8 +709,8 @@ mod pallet { ValueQuery, >; - /// Temporary storage keep track of domain runtime upgrade happen in the current block, cleared - /// in the next block initialization. + /// Temporary storage to keep track of domain runtime upgrades which happened in the parent + /// block. Cleared in the current block's initialization. #[pallet::storage] pub type DomainRuntimeUpgrades = StorageValue<_, Vec, ValueQuery>; @@ -1865,8 +1865,7 @@ mod pallet { let parent_number = block_number - One::one(); let parent_hash = frame_system::Pallet::::block_hash(parent_number); - // Record any previous domain runtime upgrade in `DomainRuntimeUpgradeRecords` and then do the - // domain runtime upgrade scheduled in the current block + // Record any previous domain runtime upgrades in `DomainRuntimeUpgradeRecords` for runtime_id in DomainRuntimeUpgrades::::take() { let reference_count = RuntimeRegistry::::get(runtime_id) .expect("Runtime object must be present since domain is insantiated; qed") @@ -1883,9 +1882,14 @@ mod pallet { }); } } + // Set DomainRuntimeUpgrades to an empty list. (If there are no runtime upgrades + // scheduled in the current block, we can generate a proof the list is empty.) + DomainRuntimeUpgrades::::set(Vec::new()); + // Do the domain runtime upgrades scheduled in the current block, and record them in + // DomainRuntimeUpgrades do_upgrade_runtimes::(block_number); - // Store the hash of the parent consensus block for domain that have bundles submitted + // Store the hash of the parent consensus block for domains that have bundles submitted // in that consensus block for (domain_id, _) in SuccessfulBundles::::drain() { ConsensusBlockHash::::insert(domain_id, parent_number, parent_hash); @@ -1896,7 +1900,8 @@ mod pallet { } for (operator_id, slot_set) in OperatorBundleSlot::::drain() { - // NOTE: `OperatorBundleSlot` use `BTreeSet` so `last` will return the maximum value in the set + // NOTE: `OperatorBundleSlot` uses `BTreeSet` so `last` will return the maximum + // value in the set if let Some(highest_slot) = slot_set.last() { OperatorHighestSlot::::insert(operator_id, highest_slot); } @@ -1908,9 +1913,10 @@ mod pallet { } fn on_finalize(_: BlockNumberFor) { - // If this consensus block will derive any domain block, gather the necessary storage for potential fraud proof usage + // If this consensus block will derive any domain block, gather the necessary storage + // for potential fraud proof usage if SuccessfulBundles::::iter_keys().count() > 0 - || DomainRuntimeUpgrades::::exists() + || !DomainRuntimeUpgrades::::get().is_empty() { let extrinsics_shuffling_seed = Randomness::from( Into::::into(Self::extrinsics_shuffling_seed()).to_fixed_bytes(), @@ -2910,7 +2916,7 @@ impl Pallet { } // Get the domain runtime code that used to derive `receipt`, if the runtime code still present in - // the state then get it from the state otherwise from the `maybe_domain_runtime_code_at` prood. + // the state then get it from the state otherwise from the `maybe_domain_runtime_code_at` proof. pub fn get_domain_runtime_code_for_receipt( domain_id: DomainId, receipt: &ExecutionReceiptOf, diff --git a/crates/pallet-domains/src/tests.rs b/crates/pallet-domains/src/tests.rs index 20f937a669..60ac88303d 100644 --- a/crates/pallet-domains/src/tests.rs +++ b/crates/pallet-domains/src/tests.rs @@ -33,10 +33,10 @@ use sp_domains::{ }; use sp_domains_fraud_proof::fraud_proof::FraudProof; use sp_runtime::traits::{ - AccountIdConversion, BlakeTwo256, BlockNumberProvider, Hash as HashT, IdentityLookup, One, + AccountIdConversion, BlakeTwo256, BlockNumberProvider, Hash as HashT, IdentityLookup, One, Zero, }; use sp_runtime::transaction_validity::TransactionValidityError; -use sp_runtime::{BuildStorage, OpaqueExtrinsic, Saturating}; +use sp_runtime::{BuildStorage, OpaqueExtrinsic}; use sp_version::RuntimeVersion; use subspace_core_primitives::U256 as P256; use subspace_runtime_primitives::{HoldIdentifier, Moment, StorageFee, SSC}; @@ -430,14 +430,20 @@ impl sp_core::traits::ReadRuntimeVersion for ReadRuntimeVersion { } pub(crate) fn run_to_block(block_number: BlockNumberFor, parent_hash: T::Hash) { - // Finalize previous block - crate::Pallet::::on_finalize(block_number.saturating_sub(One::one())); + // Finalize the previous block + // on_finalize() does not run on the genesis block + if block_number > One::one() { + crate::Pallet::::on_finalize(block_number - One::one()); + } frame_system::Pallet::::finalize(); // Initialize current block frame_system::Pallet::::set_block_number(block_number); frame_system::Pallet::::initialize(&block_number, &parent_hash, &Default::default()); - crate::Pallet::::on_initialize(block_number); + // on_initialize() does not run on the genesis block + if block_number > Zero::zero() { + crate::Pallet::::on_initialize(block_number); + } } pub(crate) fn register_genesis_domain(creator: u128, operator_ids: Vec) -> DomainId { diff --git a/crates/pallet-transaction-fees/src/lib.rs b/crates/pallet-transaction-fees/src/lib.rs index ac31cab436..1ec8b9fac4 100644 --- a/crates/pallet-transaction-fees/src/lib.rs +++ b/crates/pallet-transaction-fees/src/lib.rs @@ -21,11 +21,6 @@ pub mod weights; -#[cfg(not(feature = "std"))] -extern crate alloc; - -#[cfg(not(feature = "std"))] -use alloc::vec::Vec; use codec::{Codec, Decode, Encode}; use frame_support::sp_runtime::traits::Zero; use frame_support::sp_runtime::SaturatedConversion; diff --git a/crates/sp-domains-fraud-proof/src/fraud_proof.rs b/crates/sp-domains-fraud-proof/src/fraud_proof.rs index 149a960d6b..57ca6b6ada 100644 --- a/crates/sp-domains-fraud-proof/src/fraud_proof.rs +++ b/crates/sp-domains-fraud-proof/src/fraud_proof.rs @@ -497,9 +497,11 @@ pub struct InvalidExtrinsicsRootProof { /// The combined storage proofs used during verification pub invalid_inherent_extrinsic_proofs: InvalidInherentExtrinsicDataProof, - /// The individual storage proofs used during verification - // TODO: combine these proofs into `InvalidInherentExtrinsicDataProof` - pub invalid_inherent_extrinsic_proof: InvalidInherentExtrinsicProof, + /// Domain runtime code upgraded (or "not upgraded") storage proof + pub domain_runtime_upgraded_proof: DomainRuntimeUpgradedProof, + + /// Storage proof for a change to the chains that are allowed to open a channel with each domain + pub domain_chain_allowlist_proof: DomainChainsAllowlistUpdateStorageProof, /// Optional sudo extrinsic call storage proof pub domain_sudo_call_proof: DomainSudoCallStorageProof, diff --git a/crates/sp-domains-fraud-proof/src/storage_proof.rs b/crates/sp-domains-fraud-proof/src/storage_proof.rs index 899ea77b76..ff70b23bd0 100644 --- a/crates/sp-domains-fraud-proof/src/storage_proof.rs +++ b/crates/sp-domains-fraud-proof/src/storage_proof.rs @@ -7,10 +7,8 @@ use sp_domains::proof_provider_and_verifier::{ StorageProofVerifier, VerificationError as StorageProofVerificationError, }; use sp_domains::{ - DomainAllowlistUpdates, DomainId, DomainSudoCall, DomainsDigestItem, OpaqueBundle, RuntimeId, - RuntimeObject, + DomainAllowlistUpdates, DomainId, DomainSudoCall, OpaqueBundle, RuntimeId, RuntimeObject, }; -use sp_runtime::generic::Digest; use sp_runtime::traits::{Block as BlockT, HashingFor, Header as HeaderT, NumberFor}; use sp_runtime_interface::pass_by; use sp_runtime_interface::pass_by::PassBy; @@ -40,7 +38,7 @@ pub enum VerificationError { InvalidInherentExtrinsicStorageProof(StorageProofVerificationError), SuccessfulBundlesStorageProof(StorageProofVerificationError), DomainAllowlistUpdatesStorageProof(StorageProofVerificationError), - BlockDigestStorageProof(StorageProofVerificationError), + DomainRuntimeUpgradesStorageProof(StorageProofVerificationError), RuntimeRegistryStorageProof(StorageProofVerificationError), DigestStorageProof(StorageProofVerificationError), BlockFeesStorageProof(StorageProofVerificationError), @@ -55,7 +53,7 @@ pub enum FraudProofStorageKeyRequest { InvalidInherentExtrinsicData, SuccessfulBundles(DomainId), DomainAllowlistUpdates(DomainId), - BlockDigest, + DomainRuntimeUpgrades, RuntimeRegistry(RuntimeId), DomainSudoCall(DomainId), MmrRoot(Number), @@ -71,7 +69,9 @@ impl FraudProofStorageKeyRequest { Self::DomainAllowlistUpdates(_) => { VerificationError::DomainAllowlistUpdatesStorageProof(err) } - Self::BlockDigest => VerificationError::BlockDigestStorageProof(err), + Self::DomainRuntimeUpgrades => { + VerificationError::DomainRuntimeUpgradesStorageProof(err) + } Self::RuntimeRegistry(_) => VerificationError::RuntimeRegistryStorageProof(err), FraudProofStorageKeyRequest::DomainSudoCall(_) => { VerificationError::DomainSudoCallStorageProof(err) @@ -179,17 +179,6 @@ impl BasicStorageProof for DomainChainsAllowlistUpdateStor } } -#[derive(Clone, Debug, Decode, Encode, Eq, PartialEq, TypeInfo)] -pub struct BlockDigestProof(StorageProof); - -impl_storage_proof!(BlockDigestProof); -impl BasicStorageProof for BlockDigestProof { - type StorageValue = Digest; - fn storage_key_request(_key: Self::Key) -> FraudProofStorageKeyRequest> { - FraudProofStorageKeyRequest::BlockDigest - } -} - #[derive(Clone, Debug, Decode, Encode, Eq, PartialEq, TypeInfo)] pub struct DomainSudoCallStorageProof(StorageProof); @@ -202,7 +191,18 @@ impl BasicStorageProof for DomainSudoCallStorageProof { } } -// TODO: get the runtime id from pallet-domains since it won't change for a given domain +#[derive(Clone, Debug, Decode, Encode, Eq, PartialEq, TypeInfo)] +pub struct DomainRuntimeUpgradesProof(StorageProof); + +impl_storage_proof!(DomainRuntimeUpgradesProof); +impl BasicStorageProof for DomainRuntimeUpgradesProof { + type StorageValue = Vec; + type Key = (); + fn storage_key_request(_key: Self::Key) -> FraudProofStorageKeyRequest> { + FraudProofStorageKeyRequest::DomainRuntimeUpgrades + } +} + // The domain runtime code with storage proof // // NOTE: usually we should use the parent consensus block hash to `generate` or `verify` the @@ -287,14 +287,15 @@ where } #[derive(Clone, Debug, Decode, Encode, Eq, PartialEq, TypeInfo)] -pub struct MaybeDomainRuntimeUpgradedProof { - pub block_digest: BlockDigestProof, +pub struct DomainRuntimeUpgradedProof { + pub domain_runtime_upgrades: DomainRuntimeUpgradesProof, pub new_domain_runtime_code: Option, } -impl MaybeDomainRuntimeUpgradedProof { - /// Generate the `MaybeDomainRuntimeUpgradedProof`, it is the caller's responsibility to check - /// if the domain runtime is upgraded at `block_hash` if so the `maybe_runtime_id` should be `Some`. +impl DomainRuntimeUpgradedProof { + /// Generate the `DomainRuntimeUpgradedProof`. + /// It is the caller's responsibility to check if the domain runtime is upgraded at + /// `block_hash`. If it is, the `maybe_runtime_id` should be `Some`. #[cfg(feature = "std")] #[allow(clippy::let_and_return)] pub fn generate< @@ -307,8 +308,12 @@ impl MaybeDomainRuntimeUpgradedProof { block_hash: Block::Hash, maybe_runtime_id: Option, ) -> Result { - let block_digest = - BlockDigestProof::generate(proof_provider, block_hash, (), storage_key_provider)?; + let domain_runtime_upgrades = DomainRuntimeUpgradesProof::generate( + proof_provider, + block_hash, + (), + storage_key_provider, + )?; let new_domain_runtime_code = if let Some(runtime_id) = maybe_runtime_id { Some(DomainRuntimeCodeProof::generate( proof_provider, @@ -319,8 +324,8 @@ impl MaybeDomainRuntimeUpgradedProof { } else { None }; - Ok(MaybeDomainRuntimeUpgradedProof { - block_digest, + Ok(DomainRuntimeUpgradedProof { + domain_runtime_upgrades, new_domain_runtime_code, }) } @@ -330,17 +335,13 @@ impl MaybeDomainRuntimeUpgradedProof { runtime_id: RuntimeId, state_root: &Block::Hash, ) -> Result>, VerificationError> { - let block_digest = >::verify::( - self.block_digest.clone(), - (), - state_root, - )?; - - let runtime_upgraded = block_digest - .logs - .iter() - .filter_map(|log| log.as_domain_runtime_upgrade()) - .any(|upgraded_runtime_id| upgraded_runtime_id == runtime_id); + let domain_runtime_upgrades = + >::verify::( + self.domain_runtime_upgrades.clone(), + (), + state_root, + )?; + let runtime_upgraded = domain_runtime_upgrades.contains(&runtime_id); match (runtime_upgraded, self.new_domain_runtime_code.as_ref()) { (true, None) | (false, Some(_)) => { @@ -390,79 +391,6 @@ impl BasicStorageProof for InvalidInherentExtrinsicDataPro } } -#[derive(Clone, Debug, Decode, Encode, Eq, PartialEq, TypeInfo)] -pub struct InvalidInherentExtrinsicProof { - /// Optional domain runtime code upgrade storage proof - pub maybe_domain_runtime_upgrade_proof: MaybeDomainRuntimeUpgradedProof, - - /// Change in the allowed chains storage proof - pub domain_chain_allowlist_proof: DomainChainsAllowlistUpdateStorageProof, -} - -/// The verified data from an `InvalidInherentExtrinsicProof` -#[derive(Clone, Debug, Decode, Encode, Eq, PartialEq, TypeInfo)] -pub struct InvalidInherentExtrinsicVerified { - pub maybe_domain_runtime_upgrade: Option>, - pub domain_chain_allowlist: DomainAllowlistUpdates, -} - -impl InvalidInherentExtrinsicProof { - #[cfg(feature = "std")] - #[allow(clippy::let_and_return)] - pub fn generate< - Block: BlockT, - PP: ProofProvider, - SKP: FraudProofStorageKeyProviderInstance>, - >( - storage_key_provider: &SKP, - proof_provider: &PP, - domain_id: DomainId, - block_hash: Block::Hash, - maybe_runtime_id: Option, - ) -> Result { - let maybe_domain_runtime_upgrade_proof = MaybeDomainRuntimeUpgradedProof::generate( - storage_key_provider, - proof_provider, - block_hash, - maybe_runtime_id, - )?; - let domain_chain_allowlist_proof = DomainChainsAllowlistUpdateStorageProof::generate( - proof_provider, - block_hash, - domain_id, - storage_key_provider, - )?; - - Ok(Self { - maybe_domain_runtime_upgrade_proof, - domain_chain_allowlist_proof, - }) - } - - pub fn verify>>( - &self, - domain_id: DomainId, - runtime_id: RuntimeId, - state_root: &Block::Hash, - ) -> Result { - let maybe_domain_runtime_upgrade = self - .maybe_domain_runtime_upgrade_proof - .verify::(runtime_id, state_root)?; - - let domain_chain_allowlist = - >::verify::( - self.domain_chain_allowlist_proof.clone(), - domain_id, - state_root, - )?; - - Ok(InvalidInherentExtrinsicVerified { - maybe_domain_runtime_upgrade, - domain_chain_allowlist, - }) - } -} - #[derive(Clone, Debug, Decode, Encode, Eq, PartialEq, TypeInfo)] pub struct MmrRootStorageProof { storage_proof: StorageProof, diff --git a/crates/sp-domains-fraud-proof/src/verification.rs b/crates/sp-domains-fraud-proof/src/verification.rs index 6c4a624258..d4497adbe2 100644 --- a/crates/sp-domains-fraud-proof/src/verification.rs +++ b/crates/sp-domains-fraud-proof/src/verification.rs @@ -66,7 +66,8 @@ where let InvalidExtrinsicsRootProof { valid_bundle_digests, invalid_inherent_extrinsic_proofs, - invalid_inherent_extrinsic_proof, + domain_runtime_upgraded_proof, + domain_chain_allowlist_proof, domain_sudo_call_proof, } = fraud_proof; @@ -77,10 +78,13 @@ where &state_root, )?; - let inherent_extrinsic_verified = invalid_inherent_extrinsic_proof.verify::( - domain_id, - runtime_id, - &state_root, + let maybe_domain_runtime_upgrade = + domain_runtime_upgraded_proof.verify::(runtime_id, &state_root)?; + + let domain_chain_allowlist = >::verify::( + domain_chain_allowlist_proof.clone(), domain_id, &state_root )?; let domain_sudo_call = >::verify::( @@ -93,10 +97,10 @@ where let domain_inherent_extrinsic_data = DomainInherentExtrinsicData { timestamp: invalid_inherent_extrinsic_data.timestamp, - maybe_domain_runtime_upgrade: inherent_extrinsic_verified.maybe_domain_runtime_upgrade, + maybe_domain_runtime_upgrade, consensus_transaction_byte_fee: invalid_inherent_extrinsic_data .consensus_transaction_byte_fee, - domain_chain_allowlist: inherent_extrinsic_verified.domain_chain_allowlist, + domain_chain_allowlist, maybe_sudo_runtime_call: domain_sudo_call.maybe_call, }; diff --git a/crates/sp-domains/src/lib.rs b/crates/sp-domains/src/lib.rs index 3f169729b8..d6dcc85621 100644 --- a/crates/sp-domains/src/lib.rs +++ b/crates/sp-domains/src/lib.rs @@ -1394,9 +1394,9 @@ pub type ExecutionReceiptFor = ExecutionReceipt< /// Domain chains allowlist updates. #[derive(Default, Debug, Encode, Decode, PartialEq, Eq, Clone, TypeInfo)] pub struct DomainAllowlistUpdates { - /// Chains that are allowed to open channel with this chain. + /// Chains that are allowed to open a channel with this chain. pub allow_chains: BTreeSet, - /// Chains that are not allowed to open channel with this chain. + /// Chains that are not allowed to open a channel with this chain. pub remove_chains: BTreeSet, } diff --git a/crates/subspace-runtime/src/lib.rs b/crates/subspace-runtime/src/lib.rs index 547b7db129..0f68d7776b 100644 --- a/crates/subspace-runtime/src/lib.rs +++ b/crates/subspace-runtime/src/lib.rs @@ -1046,7 +1046,9 @@ impl FraudProofStorageKeyProvider> for StorageKeyProvider { FraudProofStorageKeyRequest::DomainAllowlistUpdates(domain_id) => { Messenger::domain_allow_list_update_storage_key(domain_id) } - FraudProofStorageKeyRequest::BlockDigest => sp_domains::system_digest_final_key(), + FraudProofStorageKeyRequest::DomainRuntimeUpgrades => { + pallet_domains::DomainRuntimeUpgrades::::hashed_key().to_vec() + } FraudProofStorageKeyRequest::RuntimeRegistry(runtime_id) => { pallet_domains::RuntimeRegistry::::hashed_key_for(runtime_id) } diff --git a/domains/client/domain-operator/src/fraud_proof.rs b/domains/client/domain-operator/src/fraud_proof.rs index 3d7d395e84..f354c04773 100644 --- a/domains/client/domain-operator/src/fraud_proof.rs +++ b/domains/client/domain-operator/src/fraud_proof.rs @@ -389,14 +389,20 @@ where &self.storage_key_provider, )?; - let invalid_inherent_extrinsic_proof = InvalidInherentExtrinsicProof::generate( + let domain_runtime_upgraded_proof = DomainRuntimeUpgradedProof::generate( &self.storage_key_provider, self.consensus_client.as_ref(), - domain_id, consensus_block_hash, maybe_runtime_id, )?; + let domain_chain_allowlist_proof = DomainChainsAllowlistUpdateStorageProof::generate( + self.consensus_client.as_ref(), + consensus_block_hash, + domain_id, + &self.storage_key_provider, + )?; + let domain_sudo_call_proof = DomainSudoCallStorageProof::generate( self.consensus_client.as_ref(), consensus_block_hash, @@ -412,7 +418,8 @@ where proof: FraudProofVariant::InvalidExtrinsicsRoot(InvalidExtrinsicsRootProof { valid_bundle_digests, invalid_inherent_extrinsic_proofs, - invalid_inherent_extrinsic_proof, + domain_runtime_upgraded_proof, + domain_chain_allowlist_proof, domain_sudo_call_proof, }), }; diff --git a/domains/client/domain-operator/src/tests.rs b/domains/client/domain-operator/src/tests.rs index e914098c86..af3ddadaf0 100644 --- a/domains/client/domain-operator/src/tests.rs +++ b/domains/client/domain-operator/src/tests.rs @@ -57,6 +57,7 @@ use sp_transaction_pool::runtime_api::TaggedTransactionQueue; use sp_weights::Weight; use std::collections::{BTreeMap, VecDeque}; use std::sync::Arc; +use std::time::Duration; use subspace_core_primitives::pot::PotOutput; use subspace_runtime_primitives::opaque::Block as CBlock; use subspace_runtime_primitives::{Balance, SSC}; @@ -64,6 +65,9 @@ use subspace_test_service::{ produce_block_with, produce_blocks, produce_blocks_until, MockConsensusNode, }; use tempfile::TempDir; +use tracing::error; + +const TIMEOUT: Duration = Duration::from_mins(2); fn number_of(consensus_node: &MockConsensusNode, block_hash: Hash) -> u32 { consensus_node @@ -1165,7 +1169,7 @@ async fn test_invalid_state_transition_proof_creation_and_verification( ) }; - // Wait for the fraud proof that target the bad ER + // Wait for the fraud proof that targets the bad ER let wait_for_fraud_proof_fut = ferdie.wait_for_fraud_proof(move |fp| { if let FraudProofVariant::InvalidStateTransition(proof) = &fp.proof { match (trace_diff_type, mismatch_trace_index) { @@ -1215,7 +1219,7 @@ async fn test_invalid_state_transition_proof_creation_and_verification( } }); - // Produce a consensus block that contains the `bad_submit_bundle_tx` and the bad receipt should + // Produce a consensus block that contains `bad_submit_bundle_tx` and the bad receipt should // be added to the consensus chain block tree produce_block_with!( ferdie.produce_block_with_slot_at( @@ -1229,14 +1233,19 @@ async fn test_invalid_state_transition_proof_creation_and_verification( .unwrap(); assert!(ferdie.does_receipt_exist(bad_receipt_hash).unwrap()); - // When the system domain node process the primary block that contains the `bad_submit_bundle_tx`, + // When the system domain node process the primary block that contains `bad_submit_bundle_tx`, // it will generate and submit a fraud proof - let _ = wait_for_fraud_proof_fut.await; + let timed_out = tokio::time::timeout(TIMEOUT, wait_for_fraud_proof_fut) + .await + .inspect_err(|_| error!("fraud proof was not created before the timeout")) + .is_err(); // Produce a consensus block that contains the fraud proof, the fraud proof wil be verified - // and executed, thus pruned the bad receipt from the block tree + // and executed, and prune the bad receipt from the block tree ferdie.produce_blocks(1).await.unwrap(); assert!(!ferdie.does_receipt_exist(bad_receipt_hash).unwrap()); + // We check for timeouts last, because they are the least useful test failure message. + assert!(!timed_out); } #[tokio::test(flavor = "multi_thread")] @@ -1318,7 +1327,7 @@ async fn test_true_invalid_bundles_inherent_extrinsic_proof_creation_and_verific bundle_to_tx(opaque_bundle) }; - // Produce a block that contains the `bad_submit_bundle_tx` + // Produce a block that contains `bad_submit_bundle_tx` produce_block_with!( ferdie.produce_block_with_slot_at( slot, @@ -1349,7 +1358,7 @@ async fn test_true_invalid_bundles_inherent_extrinsic_proof_creation_and_verific ) }; - // Wait for the fraud proof that target the bad ER + // Wait for the fraud proof that targets the bad ER let wait_for_fraud_proof_fut = ferdie.wait_for_fraud_proof(move |fp| { if let FraudProofVariant::InvalidBundles(proof) = &fp.proof { if let InvalidBundleType::InherentExtrinsic(_) = proof.invalid_bundle_type { @@ -1360,7 +1369,7 @@ async fn test_true_invalid_bundles_inherent_extrinsic_proof_creation_and_verific false }); - // Produce a consensus block that contains the `bad_submit_bundle_tx` and the bad receipt should + // Produce a consensus block that contains `bad_submit_bundle_tx` and the bad receipt should // be added to the consensus chain block tree produce_block_with!( ferdie.produce_block_with_slot_at( @@ -1374,12 +1383,17 @@ async fn test_true_invalid_bundles_inherent_extrinsic_proof_creation_and_verific .unwrap(); assert!(ferdie.does_receipt_exist(bad_receipt_hash).unwrap()); - let _ = wait_for_fraud_proof_fut.await; + let timed_out = tokio::time::timeout(TIMEOUT, wait_for_fraud_proof_fut) + .await + .inspect_err(|_| error!("fraud proof was not created before the timeout")) + .is_err(); // Produce a consensus block that contains the fraud proof, the fraud proof wil be verified - // and executed, thus pruned the bad receipt from the block tree + // and executed, and prune the bad receipt from the block tree ferdie.produce_blocks(1).await.unwrap(); assert!(!ferdie.does_receipt_exist(bad_receipt_hash).unwrap()); + // We check for timeouts last, because they are the least useful test failure message. + assert!(!timed_out); } #[tokio::test(flavor = "multi_thread")] @@ -1461,7 +1475,7 @@ async fn test_false_invalid_bundles_inherent_extrinsic_proof_creation_and_verifi ) }; - // Wait for the fraud proof that target the bad ER + // Wait for the fraud proof that targets the bad ER let wait_for_fraud_proof_fut = ferdie.wait_for_fraud_proof(move |fp| { if let FraudProofVariant::InvalidBundles(proof) = &fp.proof { if let InvalidBundleType::InherentExtrinsic(_) = proof.invalid_bundle_type { @@ -1472,7 +1486,7 @@ async fn test_false_invalid_bundles_inherent_extrinsic_proof_creation_and_verifi false }); - // Produce a consensus block that contains the `bad_submit_bundle_tx` and the bad receipt should + // Produce a consensus block that contains `bad_submit_bundle_tx` and the bad receipt should // be added to the consensus chain block tree produce_block_with!( ferdie.produce_block_with_slot_at( @@ -1486,12 +1500,17 @@ async fn test_false_invalid_bundles_inherent_extrinsic_proof_creation_and_verifi .unwrap(); assert!(ferdie.does_receipt_exist(bad_receipt_hash).unwrap()); - let _ = wait_for_fraud_proof_fut.await; + let timed_out = tokio::time::timeout(TIMEOUT, wait_for_fraud_proof_fut) + .await + .inspect_err(|_| error!("fraud proof was not created before the timeout")) + .is_err(); // Produce a consensus block that contains the fraud proof, the fraud proof wil be verified - // and executed, thus pruned the bad receipt from the block tree + // and executed, and prune the bad receipt from the block tree ferdie.produce_blocks(1).await.unwrap(); assert!(!ferdie.does_receipt_exist(bad_receipt_hash).unwrap()); + // We check for timeouts last, because they are the least useful test failure message. + assert!(!timed_out); } #[tokio::test(flavor = "multi_thread")] @@ -1571,7 +1590,7 @@ async fn test_true_invalid_bundles_undecodeable_tx_proof_creation_and_verificati bundle_to_tx(opaque_bundle) }; - // Produce a block that contains the `bad_submit_bundle_tx` + // Produce a block that contains `bad_submit_bundle_tx` produce_block_with!( ferdie.produce_block_with_slot_at( slot, @@ -1602,7 +1621,7 @@ async fn test_true_invalid_bundles_undecodeable_tx_proof_creation_and_verificati ) }; - // Wait for the fraud proof that target the bad ER + // Wait for the fraud proof that targets the bad ER let wait_for_fraud_proof_fut = ferdie.wait_for_fraud_proof(move |fp| { if let FraudProofVariant::InvalidBundles(proof) = &fp.proof { if let InvalidBundleType::UndecodableTx(_) = proof.invalid_bundle_type { @@ -1613,7 +1632,7 @@ async fn test_true_invalid_bundles_undecodeable_tx_proof_creation_and_verificati false }); - // Produce a consensus block that contains the `bad_submit_bundle_tx` and the bad receipt should + // Produce a consensus block that contains `bad_submit_bundle_tx` and the bad receipt should // be added to the consensus chain block tree produce_block_with!( ferdie.produce_block_with_slot_at( @@ -1627,12 +1646,17 @@ async fn test_true_invalid_bundles_undecodeable_tx_proof_creation_and_verificati .unwrap(); assert!(ferdie.does_receipt_exist(bad_receipt_hash).unwrap()); - let _ = wait_for_fraud_proof_fut.await; + let timed_out = tokio::time::timeout(TIMEOUT, wait_for_fraud_proof_fut) + .await + .inspect_err(|_| error!("fraud proof was not created before the timeout")) + .is_err(); // Produce a consensus block that contains the fraud proof, the fraud proof wil be verified - // and executed, thus pruned the bad receipt from the block tree + // and executed, and prune the bad receipt from the block tree ferdie.produce_blocks(1).await.unwrap(); assert!(!ferdie.does_receipt_exist(bad_receipt_hash).unwrap()); + // We check for timeouts last, because they are the least useful test failure message. + assert!(!timed_out); } #[tokio::test(flavor = "multi_thread")] @@ -1714,7 +1738,7 @@ async fn test_false_invalid_bundles_undecodeable_tx_proof_creation_and_verificat ) }; - // Wait for the fraud proof that target the bad ER + // Wait for the fraud proof that targets the bad ER let wait_for_fraud_proof_fut = ferdie.wait_for_fraud_proof(move |fp| { if let FraudProofVariant::InvalidBundles(proof) = &fp.proof { if let InvalidBundleType::UndecodableTx(_) = proof.invalid_bundle_type { @@ -1725,7 +1749,7 @@ async fn test_false_invalid_bundles_undecodeable_tx_proof_creation_and_verificat false }); - // Produce a consensus block that contains the `bad_submit_bundle_tx` and the bad receipt should + // Produce a consensus block that contains `bad_submit_bundle_tx` and the bad receipt should // be added to the consensus chain block tree produce_block_with!( ferdie.produce_block_with_slot_at( @@ -1739,12 +1763,17 @@ async fn test_false_invalid_bundles_undecodeable_tx_proof_creation_and_verificat .unwrap(); assert!(ferdie.does_receipt_exist(bad_receipt_hash).unwrap()); - let _ = wait_for_fraud_proof_fut.await; + let timed_out = tokio::time::timeout(TIMEOUT, wait_for_fraud_proof_fut) + .await + .inspect_err(|_| error!("fraud proof was not created before the timeout")) + .is_err(); // Produce a consensus block that contains the fraud proof, the fraud proof wil be verified - // and executed, thus pruned the bad receipt from the block tree + // and executed, and prune the bad receipt from the block tree ferdie.produce_blocks(1).await.unwrap(); assert!(!ferdie.does_receipt_exist(bad_receipt_hash).unwrap()); + // We check for timeouts last, because they are the least useful test failure message. + assert!(!timed_out); } #[tokio::test(flavor = "multi_thread")] @@ -1835,7 +1864,7 @@ async fn test_true_invalid_bundles_illegal_xdm_proof_creation_and_verification() bundle_to_tx(opaque_bundle) }; - // Produce a block that contains the `bad_submit_bundle_tx` + // Produce a block that contains `bad_submit_bundle_tx` produce_block_with!( ferdie.produce_block_with_slot_at( slot, @@ -1866,7 +1895,7 @@ async fn test_true_invalid_bundles_illegal_xdm_proof_creation_and_verification() ) }; - // Wait for the fraud proof that target the bad ER + // Wait for the fraud proof that targets the bad ER let wait_for_fraud_proof_fut = ferdie.wait_for_fraud_proof(move |fp| { if let FraudProofVariant::InvalidBundles(proof) = &fp.proof { if let InvalidBundleType::InvalidXDM(extrinsic_index) = proof.invalid_bundle_type { @@ -1878,9 +1907,9 @@ async fn test_true_invalid_bundles_illegal_xdm_proof_creation_and_verification() false }); - // Produce a consensus block that contains the `bad_submit_bundle_tx` and the bad receipt should + // Produce a consensus block that contains `bad_submit_bundle_tx` and the bad receipt should // be added to the consensus chain block tree - // Produce a block that contains the `bad_submit_bundle_tx` + // Produce a block that contains `bad_submit_bundle_tx` produce_block_with!( ferdie.produce_block_with_slot_at( slot, @@ -1893,12 +1922,17 @@ async fn test_true_invalid_bundles_illegal_xdm_proof_creation_and_verification() .unwrap(); assert!(ferdie.does_receipt_exist(bad_receipt_hash).unwrap()); - let _ = wait_for_fraud_proof_fut.await; + let timed_out = tokio::time::timeout(TIMEOUT, wait_for_fraud_proof_fut) + .await + .inspect_err(|_| error!("fraud proof was not created before the timeout")) + .is_err(); // Produce a consensus block that contains the fraud proof, the fraud proof wil be verified - // and executed, thus pruned the bad receipt from the block tree + // and executed, and prune the bad receipt from the block tree ferdie.produce_blocks(1).await.unwrap(); assert!(!ferdie.does_receipt_exist(bad_receipt_hash).unwrap()); + // We check for timeouts last, because they are the least useful test failure message. + assert!(!timed_out); } #[tokio::test(flavor = "multi_thread")] @@ -1999,7 +2033,7 @@ async fn test_true_invalid_bundles_illegal_extrinsic_proof_creation_and_verifica bundle_to_tx(opaque_bundle) }; - // Produce a block that contains the `bad_submit_bundle_tx` + // Produce a block that contains `bad_submit_bundle_tx` produce_block_with!( ferdie.produce_block_with_slot_at( slot, @@ -2030,7 +2064,7 @@ async fn test_true_invalid_bundles_illegal_extrinsic_proof_creation_and_verifica ) }; - // Wait for the fraud proof that target the bad ER + // Wait for the fraud proof that targets the bad ER let wait_for_fraud_proof_fut = ferdie.wait_for_fraud_proof(move |fp| { if let FraudProofVariant::InvalidBundles(proof) = &fp.proof { if let InvalidBundleType::IllegalTx(extrinsic_index) = proof.invalid_bundle_type { @@ -2042,7 +2076,7 @@ async fn test_true_invalid_bundles_illegal_extrinsic_proof_creation_and_verifica false }); - // Produce a consensus block that contains the `bad_submit_bundle_tx` and the bad receipt should + // Produce a consensus block that contains `bad_submit_bundle_tx` and the bad receipt should // be added to the consensus chain block tree produce_block_with!( ferdie.produce_block_with_slot_at( @@ -2056,12 +2090,17 @@ async fn test_true_invalid_bundles_illegal_extrinsic_proof_creation_and_verifica .unwrap(); assert!(ferdie.does_receipt_exist(bad_receipt_hash).unwrap()); - let _ = wait_for_fraud_proof_fut.await; + let timed_out = tokio::time::timeout(TIMEOUT, wait_for_fraud_proof_fut) + .await + .inspect_err(|_| error!("fraud proof was not created before the timeout")) + .is_err(); // Produce a consensus block that contains the fraud proof, the fraud proof wil be verified - // and executed, thus pruned the bad receipt from the block tree + // and executed, and prune the bad receipt from the block tree ferdie.produce_blocks(1).await.unwrap(); assert!(!ferdie.does_receipt_exist(bad_receipt_hash).unwrap()); + // We check for timeouts last, because they are the least useful test failure message. + assert!(!timed_out); } #[tokio::test(flavor = "multi_thread")] @@ -2162,7 +2201,7 @@ async fn test_false_invalid_bundles_illegal_extrinsic_proof_creation_and_verific ) }; - // Wait for the fraud proof that target the bad ER + // Wait for the fraud proof that targets the bad ER let wait_for_fraud_proof_fut = ferdie.wait_for_fraud_proof(move |fp| { if let FraudProofVariant::InvalidBundles(proof) = &fp.proof { if let InvalidBundleType::IllegalTx(extrinsic_index) = proof.invalid_bundle_type { @@ -2174,7 +2213,7 @@ async fn test_false_invalid_bundles_illegal_extrinsic_proof_creation_and_verific false }); - // Produce a consensus block that contains the `bad_submit_bundle_tx` and the bad receipt should + // Produce a consensus block that contains `bad_submit_bundle_tx` and the bad receipt should // be added to the consensus chain block tree produce_block_with!( ferdie.produce_block_with_slot_at( @@ -2188,12 +2227,17 @@ async fn test_false_invalid_bundles_illegal_extrinsic_proof_creation_and_verific .unwrap(); assert!(ferdie.does_receipt_exist(bad_receipt_hash).unwrap()); - let _ = wait_for_fraud_proof_fut.await; + let timed_out = tokio::time::timeout(TIMEOUT, wait_for_fraud_proof_fut) + .await + .inspect_err(|_| error!("fraud proof was not created before the timeout")) + .is_err(); // Produce a consensus block that contains the fraud proof, the fraud proof wil be verified - // and executed, thus pruned the bad receipt from the block tree + // and executed, and prune the bad receipt from the block tree ferdie.produce_blocks(1).await.unwrap(); assert!(!ferdie.does_receipt_exist(bad_receipt_hash).unwrap()); + // We check for timeouts last, because they are the least useful test failure message. + assert!(!timed_out); } #[tokio::test(flavor = "multi_thread")] @@ -2251,7 +2295,7 @@ async fn test_true_invalid_bundle_weight_proof_creation_and_verification() { bundle_to_tx(opaque_bundle) }; - // Produce a block that contains the `bad_submit_bundle_tx` + // Produce a block that contains `bad_submit_bundle_tx` produce_block_with!( ferdie.produce_block_with_slot_at( slot, @@ -2282,7 +2326,7 @@ async fn test_true_invalid_bundle_weight_proof_creation_and_verification() { ) }; - // Wait for the fraud proof that target the bad ER + // Wait for the fraud proof that targets the bad ER let wait_for_fraud_proof_fut = ferdie.wait_for_fraud_proof(move |fp| { if let FraudProofVariant::InvalidBundles(proof) = &fp.proof { if InvalidBundleType::InvalidBundleWeight == proof.invalid_bundle_type { @@ -2293,7 +2337,7 @@ async fn test_true_invalid_bundle_weight_proof_creation_and_verification() { false }); - // Produce a consensus block that contains the `bad_submit_bundle_tx` and the bad receipt should + // Produce a consensus block that contains `bad_submit_bundle_tx` and the bad receipt should // be added to the consensus chain block tree produce_block_with!( ferdie.produce_block_with_slot_at( @@ -2307,12 +2351,17 @@ async fn test_true_invalid_bundle_weight_proof_creation_and_verification() { .unwrap(); assert!(ferdie.does_receipt_exist(bad_receipt_hash).unwrap()); - let _ = wait_for_fraud_proof_fut.await; + let timed_out = tokio::time::timeout(TIMEOUT, wait_for_fraud_proof_fut) + .await + .inspect_err(|_| error!("fraud proof was not created before the timeout")) + .is_err(); // Produce a consensus block that contains the fraud proof, the fraud proof wil be verified - // and executed, thus pruned the bad receipt from the block tree + // and executed, and prune the bad receipt from the block tree ferdie.produce_blocks(1).await.unwrap(); assert!(!ferdie.does_receipt_exist(bad_receipt_hash).unwrap()); + // We check for timeouts last, because they are the least useful test failure message. + assert!(!timed_out); } #[tokio::test(flavor = "multi_thread")] @@ -2392,7 +2441,7 @@ async fn test_false_invalid_bundle_weight_proof_creation_and_verification() { ) }; - // Wait for the fraud proof that target the bad ER + // Wait for the fraud proof that targets the bad ER let wait_for_fraud_proof_fut = ferdie.wait_for_fraud_proof(move |fp| { if let FraudProofVariant::InvalidBundles(proof) = &fp.proof { if InvalidBundleType::InvalidBundleWeight == proof.invalid_bundle_type { @@ -2403,7 +2452,7 @@ async fn test_false_invalid_bundle_weight_proof_creation_and_verification() { false }); - // Produce a consensus block that contains the `bad_submit_bundle_tx` and the bad receipt should + // Produce a consensus block that contains `bad_submit_bundle_tx` and the bad receipt should // be added to the consensus chain block tree produce_block_with!( ferdie.produce_block_with_slot_at( @@ -2417,12 +2466,17 @@ async fn test_false_invalid_bundle_weight_proof_creation_and_verification() { .unwrap(); assert!(ferdie.does_receipt_exist(bad_receipt_hash).unwrap()); - let _ = wait_for_fraud_proof_fut.await; + let timed_out = tokio::time::timeout(TIMEOUT, wait_for_fraud_proof_fut) + .await + .inspect_err(|_| error!("fraud proof was not created before the timeout")) + .is_err(); // Produce a consensus block that contains the fraud proof, the fraud proof wil be verified - // and executed, thus pruned the bad receipt from the block tree + // and executed, and prune the bad receipt from the block tree ferdie.produce_blocks(1).await.unwrap(); assert!(!ferdie.does_receipt_exist(bad_receipt_hash).unwrap()); + // We check for timeouts last, because they are the least useful test failure message. + assert!(!timed_out); } #[tokio::test(flavor = "multi_thread")] @@ -2503,7 +2557,7 @@ async fn test_false_invalid_bundles_non_exist_extrinsic_proof_creation_and_verif ) }; - // Wait for the fraud proof that target the bad ER + // Wait for the fraud proof that targets the bad ER let wait_for_fraud_proof_fut = ferdie.wait_for_fraud_proof(move |fp| { if let FraudProofVariant::InvalidBundles(proof) = &fp.proof { if let InvalidBundlesProofData::Bundle(_) = proof.proof_data { @@ -2514,7 +2568,7 @@ async fn test_false_invalid_bundles_non_exist_extrinsic_proof_creation_and_verif false }); - // Produce a consensus block that contains the `bad_submit_bundle_tx` and the bad receipt should + // Produce a consensus block that contains `bad_submit_bundle_tx` and the bad receipt should // be added to the consensus chain block tree produce_block_with!( ferdie.produce_block_with_slot_at( @@ -2528,12 +2582,17 @@ async fn test_false_invalid_bundles_non_exist_extrinsic_proof_creation_and_verif .unwrap(); assert!(ferdie.does_receipt_exist(bad_receipt_hash).unwrap()); - let _ = wait_for_fraud_proof_fut.await; + let timed_out = tokio::time::timeout(TIMEOUT, wait_for_fraud_proof_fut) + .await + .inspect_err(|_| error!("fraud proof was not created before the timeout")) + .is_err(); // Produce a consensus block that contains the fraud proof, the fraud proof wil be verified - // and executed, thus pruned the bad receipt from the block tree + // and executed, and prune the bad receipt from the block tree ferdie.produce_blocks(1).await.unwrap(); assert!(!ferdie.does_receipt_exist(bad_receipt_hash).unwrap()); + // We check for timeouts last, because they are the least useful test failure message. + assert!(!timed_out); } #[tokio::test(flavor = "multi_thread")] @@ -2585,7 +2644,7 @@ async fn test_invalid_block_fees_proof_creation() { ) }; - // Wait for the fraud proof that target the bad ER + // Wait for the fraud proof that targets the bad ER let wait_for_fraud_proof_fut = ferdie.wait_for_fraud_proof(move |fp| { matches!( fp.proof, @@ -2593,7 +2652,7 @@ async fn test_invalid_block_fees_proof_creation() { ) }); - // Produce a consensus block that contains the `bad_submit_bundle_tx` and the bad receipt should + // Produce a consensus block that contains `bad_submit_bundle_tx` and the bad receipt should // be added to the consensus chain block tree produce_block_with!( ferdie.produce_block_with_slot_at( @@ -2607,14 +2666,19 @@ async fn test_invalid_block_fees_proof_creation() { .unwrap(); assert!(ferdie.does_receipt_exist(bad_receipt_hash).unwrap()); - // When the domain node operator process the primary block that contains the `bad_submit_bundle_tx`, + // When the domain node operator processes the primary block that contains `bad_submit_bundle_tx`, // it will generate and submit a fraud proof - let _ = wait_for_fraud_proof_fut.await; + let timed_out = tokio::time::timeout(TIMEOUT, wait_for_fraud_proof_fut) + .await + .inspect_err(|_| error!("fraud proof was not created before the timeout")) + .is_err(); // Produce a consensus block that contains the fraud proof, the fraud proof wil be verified - // and executed, thus pruned the bad receipt from the block tree + // and executed, and prune the bad receipt from the block tree ferdie.produce_blocks(1).await.unwrap(); assert!(!ferdie.does_receipt_exist(bad_receipt_hash).unwrap()); + // We check for timeouts last, because they are the least useful test failure message. + assert!(!timed_out); } #[tokio::test(flavor = "multi_thread")] @@ -2686,7 +2750,7 @@ async fn test_invalid_transfers_fraud_proof() { ) }; - // Wait for the fraud proof that target the bad ER + // Wait for the fraud proof that targets the bad ER let wait_for_fraud_proof_fut = ferdie.wait_for_fraud_proof(move |fp| { matches!( fp.proof, @@ -2694,7 +2758,7 @@ async fn test_invalid_transfers_fraud_proof() { ) }); - // Produce a consensus block that contains the `bad_submit_bundle_tx` and the bad receipt should + // Produce a consensus block that contains `bad_submit_bundle_tx` and the bad receipt should // be added to the consensus chain block tree produce_block_with!( ferdie.produce_block_with_slot_at( @@ -2708,14 +2772,19 @@ async fn test_invalid_transfers_fraud_proof() { .unwrap(); assert!(ferdie.does_receipt_exist(bad_receipt_hash).unwrap()); - // When the domain node operator process the primary block that contains the `bad_submit_bundle_tx`, + // When the domain node operator processes the primary block that contains `bad_submit_bundle_tx`, // it will generate and submit a fraud proof - let _ = wait_for_fraud_proof_fut.await; + let timed_out = tokio::time::timeout(TIMEOUT, wait_for_fraud_proof_fut) + .await + .inspect_err(|_| error!("fraud proof was not created before the timeout")) + .is_err(); // Produce a consensus block that contains the fraud proof, the fraud proof wil be verified - // and executed, thus pruned the bad receipt from the block tree + // and executed, and prune the bad receipt from the block tree ferdie.produce_blocks(1).await.unwrap(); assert!(!ferdie.does_receipt_exist(bad_receipt_hash).unwrap()); + // We check for timeouts last, because they are the least useful test failure message. + assert!(!timed_out); } #[tokio::test(flavor = "multi_thread")] @@ -2782,7 +2851,7 @@ async fn test_invalid_domain_block_hash_proof_creation() { ) }; - // Wait for the fraud proof that target the bad ER + // Wait for the fraud proof that targets the bad ER let wait_for_fraud_proof_fut = ferdie.wait_for_fraud_proof(move |fp| { matches!( fp.proof, @@ -2790,7 +2859,7 @@ async fn test_invalid_domain_block_hash_proof_creation() { ) }); - // Produce a consensus block that contains the `bad_submit_bundle_tx` and the bad receipt should + // Produce a consensus block that contains `bad_submit_bundle_tx` and the bad receipt should // be added to the consensus chain block tree produce_block_with!( ferdie.produce_block_with_slot_at( @@ -2804,14 +2873,19 @@ async fn test_invalid_domain_block_hash_proof_creation() { .unwrap(); assert!(ferdie.does_receipt_exist(bad_receipt_hash).unwrap()); - // When the domain node operator process the primary block that contains the `bad_submit_bundle_tx`, + // When the domain node operator processes the primary block that contains `bad_submit_bundle_tx`, // it will generate and submit a fraud proof - let _ = wait_for_fraud_proof_fut.await; + let timed_out = tokio::time::timeout(TIMEOUT, wait_for_fraud_proof_fut) + .await + .inspect_err(|_| error!("fraud proof was not created before the timeout")) + .is_err(); // Produce a consensus block that contains the fraud proof, the fraud proof wil be verified - // and executed, thus pruned the bad receipt from the block tree + // and executed, and prune the bad receipt from the block tree ferdie.produce_blocks(1).await.unwrap(); assert!(!ferdie.does_receipt_exist(bad_receipt_hash).unwrap()); + // We check for timeouts last, because they are the least useful test failure message. + assert!(!timed_out); } #[tokio::test(flavor = "multi_thread")] @@ -2878,7 +2952,7 @@ async fn test_invalid_domain_extrinsics_root_proof_creation() { ) }; - // Wait for the fraud proof that target the bad ER + // Wait for the fraud proof that targets the bad ER let wait_for_fraud_proof_fut = ferdie.wait_for_fraud_proof(move |fp| { matches!( fp.proof, @@ -2886,7 +2960,7 @@ async fn test_invalid_domain_extrinsics_root_proof_creation() { ) }); - // Produce a consensus block that contains the `bad_submit_bundle_tx` and the bad receipt should + // Produce a consensus block that contains `bad_submit_bundle_tx` and the bad receipt should // be added to the consensus chain block tree produce_block_with!( ferdie.produce_block_with_slot_at( @@ -2900,14 +2974,19 @@ async fn test_invalid_domain_extrinsics_root_proof_creation() { .unwrap(); assert!(ferdie.does_receipt_exist(bad_receipt_hash).unwrap()); - // When the domain node operator process the primary block that contains the `bad_submit_bundle_tx`, + // When the domain node operator processes the primary block that contains `bad_submit_bundle_tx`, // it will generate and submit a fraud proof - let _ = wait_for_fraud_proof_fut.await; + let timed_out = tokio::time::timeout(TIMEOUT, wait_for_fraud_proof_fut) + .await + .inspect_err(|_| error!("fraud proof was not created before the timeout")) + .is_err(); // Produce a consensus block that contains the fraud proof, the fraud proof wil be verified - // and executed, thus pruned the bad receipt from the block tree + // and executed, and prune the bad receipt from the block tree ferdie.produce_blocks(1).await.unwrap(); assert!(!ferdie.does_receipt_exist(bad_receipt_hash).unwrap()); + // We check for timeouts last, because they are the least useful test failure message. + assert!(!timed_out); } #[tokio::test(flavor = "multi_thread")] @@ -3177,7 +3256,7 @@ async fn test_valid_bundle_proof_generation_and_verification() { (bundle.receipt().clone(), bundle_to_tx(bundle)) }; - // Produce a consensus block that contains the `bad_submit_bundle_tx` and the bad receipt should + // Produce a consensus block that contains `bad_submit_bundle_tx` and the bad receipt should // be added to the consensus chain block tree let mut import_tx_stream = ferdie.transaction_pool.import_notification_stream(); produce_block_with!( @@ -3194,7 +3273,7 @@ async fn test_valid_bundle_proof_generation_and_verification() { .does_receipt_exist(bad_receipt.hash::()) .unwrap()); - // When the domain node operator process the primary block that contains the `bad_submit_bundle_tx`, + // When the domain node operator processes the primary block that contains `bad_submit_bundle_tx`, // it will generate and submit a fraud proof while let Some(ready_tx_hash) = import_tx_stream.next().await { let ready_tx = ferdie @@ -3239,7 +3318,7 @@ async fn test_valid_bundle_proof_generation_and_verification() { } // Produce a consensus block that contains the fraud proof, the fraud proof wil be verified - // and executed, thus pruned the bad receipt from the block tree + // and executed, and prune the bad receipt from the block tree ferdie.produce_blocks(1).await.unwrap(); assert!(!ferdie .does_receipt_exist(bad_receipt.hash::()) @@ -4664,7 +4743,7 @@ async fn test_bad_receipt_chain() { ) }; - // Produce a consensus block that contains the `bad_submit_bundle_tx` and the bad receipt should + // Produce a consensus block that contains `bad_submit_bundle_tx` and the bad receipt should // be added to the consensus chain block tree produce_block_with!( ferdie.produce_block_with_slot_at( @@ -4689,7 +4768,7 @@ async fn test_bad_receipt_chain() { ) && fp.targeted_bad_receipt_hash() == bad_receipt_hash }); - // Produce more bundle with bad ER that use previous bad ER as parent + // Produce more bundles with bad ERs that use the previous bad ER as an ancestor let mut parent_bad_receipt_hash = bad_receipt_hash; let mut bad_receipt_descendants = vec![]; for _ in 0..7 { @@ -4738,9 +4817,12 @@ async fn test_bad_receipt_chain() { } // The fraud proof should be submitted - let _ = wait_for_fraud_proof_fut.await; + let timed_out = tokio::time::timeout(TIMEOUT, wait_for_fraud_proof_fut) + .await + .inspect_err(|_| error!("fraud proof was not created before the timeout")) + .is_err(); - // The first bad ER should be pruned and its descendants are marked as pending to prune + // The first bad ER should be pruned, and its descendants marked as pending to prune ferdie.produce_blocks(1).await.unwrap(); assert!(!ferdie.does_receipt_exist(bad_receipt_hash).unwrap()); @@ -4766,7 +4848,7 @@ async fn test_bad_receipt_chain() { .head_receipt_number(ferdie_best_hash, EVM_DOMAIN_ID) .unwrap(); assert_eq!(head_domain_number - head_receipt_number, 9); - // The previou bundle will be rejected as there is a receipt gap + // The previous bundle will be rejected as there is a receipt gap match ferdie .submit_transaction(bundle_to_tx(stale_bundle)) .await @@ -4821,7 +4903,7 @@ async fn test_bad_receipt_chain() { let bob_best_number = bob.client.info().best_number; assert_eq!(alice_best_number, bob_best_number); - // Bad receipt should be pruned as singletone receipt submitting + // The bad receipt and its descendants should be pruned immediately for receipt_hash in vec![bad_receipt_hash] .into_iter() .chain(bad_receipt_descendants) @@ -4832,7 +4914,7 @@ async fn test_bad_receipt_chain() { assert!(!ferdie.does_receipt_exist(receipt_hash).unwrap()); } - // The receipt gap should be fill up + // The receipt gap should be filled up let ferdie_best_hash = ferdie.client.info().best_hash; let head_domain_number = ferdie .client @@ -4849,6 +4931,8 @@ async fn test_bad_receipt_chain() { assert_eq!(bob_best_number, bob.client.info().best_number); produce_blocks!(ferdie, bob, 15).await.unwrap(); + // We check for timeouts last, because they are the least useful test failure message. + assert!(!timed_out); } #[tokio::test(flavor = "multi_thread")] @@ -5430,7 +5514,7 @@ async fn test_xdm_false_invalid_fraud_proof() { ) }; - // Wait for the fraud proof that target the bad ER + // Wait for the fraud proof that targets the bad ER let wait_for_fraud_proof_fut = ferdie.wait_for_fraud_proof(move |fp| { if let FraudProofVariant::InvalidBundles(proof) = &fp.proof { if let InvalidBundleType::InvalidXDM(extrinsic_index) = proof.invalid_bundle_type { @@ -5442,9 +5526,9 @@ async fn test_xdm_false_invalid_fraud_proof() { false }); - // Produce a consensus block that contains the `bad_submit_bundle_tx` and the bad receipt should + // Produce a consensus block that contains `bad_submit_bundle_tx` and the bad receipt should // be added to the consensus chain block tree - // Produce a block that contains the `bad_submit_bundle_tx` + // Produce a block that contains `bad_submit_bundle_tx` produce_block_with!( ferdie.produce_block_with_slot_at( slot, @@ -5457,12 +5541,17 @@ async fn test_xdm_false_invalid_fraud_proof() { .unwrap(); assert!(ferdie.does_receipt_exist(bad_receipt_hash).unwrap()); - let _ = wait_for_fraud_proof_fut.await; + let timed_out = tokio::time::timeout(TIMEOUT, wait_for_fraud_proof_fut) + .await + .inspect_err(|_| error!("fraud proof was not created before the timeout")) + .is_err(); // Produce a consensus block that contains the fraud proof, the fraud proof wil be verified - // and executed, thus pruned the bad receipt from the block tree + // and executed, and prune the bad receipt from the block tree ferdie.produce_blocks(1).await.unwrap(); assert!(!ferdie.does_receipt_exist(bad_receipt_hash).unwrap()); + // We check for timeouts last, because they are the least useful test failure message. + assert!(!timed_out); } // TODO: this test is flaky and sometime hang forever in CI thus disable it temporary, @@ -5676,7 +5765,7 @@ async fn test_stale_fork_xdm_true_invalid_fraud_proof() { ) }; - // Wait for the fraud proof that target the bad ER + // Wait for the fraud proof that targets the bad ER let wait_for_fraud_proof_fut = ferdie.wait_for_fraud_proof(move |fp| { if let FraudProofVariant::InvalidBundles(proof) = &fp.proof { if let InvalidBundleType::InvalidXDM(extrinsic_index) = proof.invalid_bundle_type { @@ -5688,9 +5777,9 @@ async fn test_stale_fork_xdm_true_invalid_fraud_proof() { false }); - // Produce a consensus block that contains the `bad_submit_bundle_tx` and the bad receipt should + // Produce a consensus block that contains `bad_submit_bundle_tx` and the bad receipt should // be added to the consensus chain block tree - // Produce a block that contains the `bad_submit_bundle_tx` + // Produce a block that contains `bad_submit_bundle_tx` produce_block_with!( ferdie.produce_block_with_slot_at( slot, @@ -5703,10 +5792,15 @@ async fn test_stale_fork_xdm_true_invalid_fraud_proof() { .unwrap(); assert!(ferdie.does_receipt_exist(bad_receipt_hash).unwrap()); - let _ = wait_for_fraud_proof_fut.await; + let timed_out = tokio::time::timeout(TIMEOUT, wait_for_fraud_proof_fut) + .await + .inspect_err(|_| error!("fraud proof was not created before the timeout")) + .is_err(); // Produce a consensus block that contains the fraud proof, the fraud proof wil be verified - // and executed, thus pruned the bad receipt from the block tree + // and executed, and prune the bad receipt from the block tree ferdie.produce_blocks(1).await.unwrap(); assert!(!ferdie.does_receipt_exist(bad_receipt_hash).unwrap()); + // We check for timeouts last, because they are the least useful test failure message. + assert!(!timed_out); } diff --git a/test/subspace-test-runtime/src/lib.rs b/test/subspace-test-runtime/src/lib.rs index fdbb1cdfd5..6de8225fdf 100644 --- a/test/subspace-test-runtime/src/lib.rs +++ b/test/subspace-test-runtime/src/lib.rs @@ -1117,7 +1117,9 @@ impl FraudProofStorageKeyProvider> for StorageKeyProvider { FraudProofStorageKeyRequest::DomainAllowlistUpdates(domain_id) => { Messenger::domain_allow_list_update_storage_key(domain_id) } - FraudProofStorageKeyRequest::BlockDigest => sp_domains::system_digest_final_key(), + FraudProofStorageKeyRequest::DomainRuntimeUpgrades => { + pallet_domains::DomainRuntimeUpgrades::::hashed_key().to_vec() + } FraudProofStorageKeyRequest::RuntimeRegistry(runtime_id) => { pallet_domains::RuntimeRegistry::::hashed_key_for(runtime_id) } diff --git a/test/subspace-test-service/src/lib.rs b/test/subspace-test-service/src/lib.rs index 8e0efe006a..f493a68abf 100644 --- a/test/subspace-test-service/src/lib.rs +++ b/test/subspace-test-service/src/lib.rs @@ -809,11 +809,11 @@ impl MockConsensusNode { .is_some()) } - /// Return a future that only resolve if a fraud proof that the given `fraud_proof_predict` + /// Return a future that only resolve if a fraud proof that the given `fraud_proof_predicate` /// return true is submitted to the consensus tx pool pub fn wait_for_fraud_proof( &self, - fraud_proof_predict: FP, + fraud_proof_predicate: FP, ) -> Pin + Send>> where FP: Fn(&FraudProofFor) -> bool + Send + 'static, @@ -833,7 +833,7 @@ impl MockConsensusNode { pallet_domains::Call::submit_fraud_proof { fraud_proof }, ) = ext.function { - if fraud_proof_predict(&fraud_proof) { + if fraud_proof_predicate(&fraud_proof) { break; } }