diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index a65718da81..d78346322c 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,16 +1,25 @@ -# Order matters -# below ones takes precedence over the upper ones +# Order matters: entries that are further down override any entries above them -# Global owners -* @nazar-pc @rg3l3dr - -/crates @nazar-pc @rg3l3dr -/crates/pallet-* @nazar-pc @rg3l3dr @vedhavyas @NingLin-P -/crates/sp-* @nazar-pc @rg3l3dr @vedhavyas @NingLin-P -/crates/subspace-archiving @shamil-gadelshin @nazar-pc @rg3l3dr -/crates/subspace-farmer @nazar-pc @shamil-gadelshin @rg3l3dr -/crates/subspace-networking @shamil-gadelshin @nazar-pc @rg3l3dr -/crates/subspace-runtime* @vedhavyas @nazar-pc @rg3l3dr -/crates/subspace-node @NingLin-P @nazar-pc @rg3l3dr @vedhavyas -/crates/substrate @nazar-pc @rg3l3dr -/domains @vedhavyas @NingLin-P @nazar-pc @rg3l3dr +/.github/workflows @nazar-pc +/crates/pallet-* @NingLin-P @vedhavyas +/crates/pallet-subspace @NingLin-P @vedhavyas @nazar-pc +/crates/sc-consensus-* @nazar-pc +/crates/sc-proof-of-time @nazar-pc +/crates/sp-* @NingLin-P @vedhavyas +/crates/sp-consensus-subspace @NingLin-P @vedhavyas @nazar-pc +/crates/subspace-archiving @nazar-pc @shamil-gadelshin +/crates/subspace-core-primitives @nazar-pc +/crates/subspace-erasure-coding @nazar-pc +/crates/subspace-farmer* @nazar-pc @shamil-gadelshin +/crates/subspace-networking @nazar-pc @shamil-gadelshin +/crates/subspace-proof-* @nazar-pc +/crates/subspace-rpc-primitives @nazar-pc +/crates/subspace-runtime* @vedhavyas @nazar-pc +/crates/subspace-service @nazar-pc +/crates/subspace-node @NingLin-P @vedhavyas @nazar-pc +/crates/subspace-verification @nazar-pc +/docker @nazar-pc +/domains @NingLin-P @vedhavyas +/shared/subspace-kzg @nazar-pc +/shared/subspace-proof-* @nazar-pc +/Cargo.toml @nazar-pc diff --git a/Cargo.lock b/Cargo.lock index 35d19fbc46..b48bc57df2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13001,7 +13001,6 @@ dependencies = [ "criterion", "derive_more 1.0.0", "parking_lot 0.12.3", - "rand", "rayon", "seq-macro", "sha2 0.10.8", diff --git a/crates/pallet-domains/src/lib.rs b/crates/pallet-domains/src/lib.rs index 80b2373522..aab92ac09f 100644 --- a/crates/pallet-domains/src/lib.rs +++ b/crates/pallet-domains/src/lib.rs @@ -201,6 +201,7 @@ mod pallet { #[cfg(not(feature = "runtime-benchmarks"))] use crate::staking_epoch::do_slash_operator; use crate::staking_epoch::{do_finalize_domain_current_epoch, Error as StakingEpochError}; + use crate::storage_proof::InvalidInherentExtrinsicData; use crate::weights::WeightInfo; #[cfg(not(feature = "runtime-benchmarks"))] use crate::DomainHashingFor; @@ -222,7 +223,7 @@ mod pallet { use frame_support::pallet_prelude::*; use frame_support::traits::fungible::{Inspect, InspectHold, Mutate, MutateHold}; use frame_support::traits::tokens::Preservation; - use frame_support::traits::Randomness as RandomnessT; + use frame_support::traits::{Randomness as RandomnessT, Time}; use frame_support::weights::Weight; use frame_support::{Identity, PalletError}; use frame_system::pallet_prelude::*; @@ -246,8 +247,8 @@ mod pallet { use sp_std::collections::btree_set::BTreeSet; use sp_std::fmt::Debug; use sp_subspace_mmr::MmrProofVerifier; - use subspace_core_primitives::U256; - use subspace_runtime_primitives::StorageFee; + use subspace_core_primitives::{Randomness, U256}; + use subspace_runtime_primitives::{Balance, StorageFee}; #[pallet::config] pub trait Config: frame_system::Config> { @@ -389,6 +390,9 @@ mod pallet { /// Storage fee interface used to deal with bundle storage fee type StorageFee: StorageFee>; + /// The block timestamp + type BlockTimestamp: Time; + /// The block slot type BlockSlot: BlockSlot; @@ -1850,6 +1854,10 @@ mod pallet { } } + /// Combined fraud proof data for the InvalidInherentExtrinsic fraud proof + #[pallet::storage] + pub type BlockInvalidInherentExtrinsicData = StorageValue<_, InvalidInherentExtrinsicData>; + #[pallet::hooks] // TODO: proper benchmark impl Hooks> for Pallet { @@ -1894,10 +1902,44 @@ mod pallet { } } + BlockInvalidInherentExtrinsicData::::kill(); + Weight::zero() } fn on_finalize(_: BlockNumberFor) { + // 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() + { + let extrinsics_shuffling_seed = Randomness::from( + Into::::into(Self::extrinsics_shuffling_seed()).to_fixed_bytes(), + ); + + // There are no actual conversions here, but the trait bounds required to prove that + // (and debug-print the error in expect()) are very verbose. + let timestamp = T::BlockTimestamp::now() + .try_into() + .map_err(|_| ()) + .expect("Moment is the same type in both pallets; qed"); + let transaction_byte_fee: Balance = T::StorageFee::transaction_byte_fee() + .try_into() + .map_err(|_| ()) + .expect("Balance is the same type in both pallets; qed"); + + // The value returned by the consensus_chain_byte_fee() runtime API + let consensus_transaction_byte_fee = + sp_domains::DOMAIN_STORAGE_FEE_MULTIPLIER * transaction_byte_fee; + + let invalid_inherent_extrinsic_data = InvalidInherentExtrinsicData { + extrinsics_shuffling_seed, + timestamp, + consensus_transaction_byte_fee, + }; + + BlockInvalidInherentExtrinsicData::::set(Some(invalid_inherent_extrinsic_data)); + } + let _ = LastEpochStakingDistribution::::clear(u32::MAX, None); let _ = NewAddedHeadReceipt::::clear(u32::MAX, None); } @@ -2717,8 +2759,8 @@ impl Pallet { } pub fn extrinsics_shuffling_seed() -> T::Hash { - let seed = DOMAIN_EXTRINSICS_SHUFFLING_SEED_SUBJECT; - let (randomness, _) = T::Randomness::random(seed); + let subject = DOMAIN_EXTRINSICS_SHUFFLING_SEED_SUBJECT; + let (randomness, _) = T::Randomness::random(subject); randomness } @@ -2889,9 +2931,9 @@ impl Pallet { parent_receipt.consensus_block_number }; - let is_domain_runtime_updraded = current_runtime_obj.updated_at >= at; + let is_domain_runtime_upgraded = current_runtime_obj.updated_at >= at; - let mut runtime_obj = match (is_domain_runtime_updraded, maybe_domain_runtime_code_at) { + let mut runtime_obj = match (is_domain_runtime_upgraded, maybe_domain_runtime_code_at) { // The domain runtime is upgraded since `at`, the domain runtime code in `at` is not available // so `domain_runtime_code_proof` must be provided (true, None) => return Err(FraudProofError::DomainRuntimeCodeProofNotFound), diff --git a/crates/pallet-domains/src/tests.rs b/crates/pallet-domains/src/tests.rs index 2459685bd7..20f937a669 100644 --- a/crates/pallet-domains/src/tests.rs +++ b/crates/pallet-domains/src/tests.rs @@ -263,6 +263,7 @@ impl pallet_domains::Config for Test { type Randomness = MockRandomness; type PalletId = DomainsPalletId; type StorageFee = DummyStorageFee; + type BlockTimestamp = pallet_timestamp::Pallet; type BlockSlot = DummyBlockSlot; type DomainsTransfersTracker = MockDomainsTransfersTracker; type MaxInitialDomainAccounts = MaxInitialDomainAccounts; diff --git a/crates/pallet-transaction-fees/src/lib.rs b/crates/pallet-transaction-fees/src/lib.rs index 2558526451..ac31cab436 100644 --- a/crates/pallet-transaction-fees/src/lib.rs +++ b/crates/pallet-transaction-fees/src/lib.rs @@ -242,10 +242,6 @@ where } } - pub fn transaction_byte_fee_storage_key() -> Vec { - TransactionByteFee::::hashed_key().to_vec() - } - pub fn calculate_transaction_byte_fee() -> BalanceOf { let credit_supply = T::CreditSupply::get(); diff --git a/crates/sc-consensus-subspace/src/archiver.rs b/crates/sc-consensus-subspace/src/archiver.rs index 3109104e5f..9344f633be 100644 --- a/crates/sc-consensus-subspace/src/archiver.rs +++ b/crates/sc-consensus-subspace/src/archiver.rs @@ -452,9 +452,10 @@ where continue; }; - let last_archived_block = client - .block(last_archived_block_hash)? - .expect("Last archived block must always be retrievable; qed"); + let Some(last_archived_block) = client.block(last_archived_block_hash)? else { + // This block data was already pruned (but the headers weren't) + continue; + }; // If we're starting mapping creation at this block, return its mappings. let block_object_mappings = if create_object_mappings { diff --git a/crates/sp-domains-fraud-proof/src/fraud_proof.rs b/crates/sp-domains-fraud-proof/src/fraud_proof.rs index 157b4c3280..149a960d6b 100644 --- a/crates/sp-domains-fraud-proof/src/fraud_proof.rs +++ b/crates/sp-domains-fraud-proof/src/fraud_proof.rs @@ -494,7 +494,11 @@ pub struct InvalidExtrinsicsRootProof { /// Valid Bundle digests pub valid_bundle_digests: Vec, - /// The storage proof used during verification + /// 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, /// Optional sudo extrinsic call storage proof diff --git a/crates/sp-domains-fraud-proof/src/host_functions.rs b/crates/sp-domains-fraud-proof/src/host_functions.rs index 21add775b0..eede593383 100644 --- a/crates/sp-domains-fraud-proof/src/host_functions.rs +++ b/crates/sp-domains-fraud-proof/src/host_functions.rs @@ -262,8 +262,6 @@ where domain_inherent_extrinsic_data: DomainInherentExtrinsicData, ) -> Option { let DomainInherentExtrinsicData { - // Used by caller - block_randomness: _, timestamp, maybe_domain_runtime_upgrade, consensus_transaction_byte_fee, diff --git a/crates/sp-domains-fraud-proof/src/lib.rs b/crates/sp-domains-fraud-proof/src/lib.rs index 24f30cfa7c..7139e1252f 100644 --- a/crates/sp-domains-fraud-proof/src/lib.rs +++ b/crates/sp-domains-fraud-proof/src/lib.rs @@ -54,7 +54,7 @@ use sp_runtime::transaction_validity::{InvalidTransaction, TransactionValidity}; use sp_runtime::OpaqueExtrinsic; use sp_runtime_interface::pass_by; use sp_runtime_interface::pass_by::PassBy; -use subspace_core_primitives::{Randomness, U256}; +use subspace_core_primitives::U256; use subspace_runtime_primitives::{Balance, Moment}; /// Custom invalid validity code for the extrinsics in pallet-domains. @@ -108,7 +108,6 @@ pub enum DomainChainAllowlistUpdateExtrinsic { #[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone)] pub struct DomainInherentExtrinsicData { - pub block_randomness: Randomness, pub timestamp: Moment, pub maybe_domain_runtime_upgrade: Option>, pub consensus_transaction_byte_fee: Balance, @@ -161,7 +160,7 @@ sp_api::decl_runtime_apis! { /// Submit the fraud proof via an unsigned extrinsic. fn submit_fraud_proof_unsigned(fraud_proof: FraudProof, Block::Hash, DomainHeader, H256>); - /// Reture the storage key used in fraud proof + /// Return the storage key used in fraud proof fn fraud_proof_storage_key(req: FraudProofStorageKeyRequest>) -> Vec; } } diff --git a/crates/sp-domains-fraud-proof/src/storage_proof.rs b/crates/sp-domains-fraud-proof/src/storage_proof.rs index e0c15e3db7..899ea77b76 100644 --- a/crates/sp-domains-fraud-proof/src/storage_proof.rs +++ b/crates/sp-domains-fraud-proof/src/storage_proof.rs @@ -1,4 +1,3 @@ -use crate::DomainInherentExtrinsicData; use codec::{Decode, Encode}; use frame_support::PalletError; use scale_info::TypeInfo; @@ -13,11 +12,13 @@ use sp_domains::{ }; 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; use sp_std::marker::PhantomData; use sp_std::vec::Vec; use sp_trie::StorageProof; use subspace_core_primitives::Randomness; -use subspace_runtime_primitives::{Balance, BlockTransactionByteFee, Moment}; +use subspace_runtime_primitives::{Balance, Moment}; #[cfg(feature = "std")] use sc_client_api::ProofProvider; @@ -36,14 +37,11 @@ pub enum VerificationError { InvalidBundleStorageProof, RuntimeCodeNotFound, UnexpectedDomainRuntimeUpgrade, - BlockRandomnessStorageProof(StorageProofVerificationError), - TimestampStorageProof(StorageProofVerificationError), + InvalidInherentExtrinsicStorageProof(StorageProofVerificationError), SuccessfulBundlesStorageProof(StorageProofVerificationError), - TransactionByteFeeStorageProof(StorageProofVerificationError), DomainAllowlistUpdatesStorageProof(StorageProofVerificationError), BlockDigestStorageProof(StorageProofVerificationError), RuntimeRegistryStorageProof(StorageProofVerificationError), - DynamicCostOfStorageStorageProof(StorageProofVerificationError), DigestStorageProof(StorageProofVerificationError), BlockFeesStorageProof(StorageProofVerificationError), TransfersStorageProof(StorageProofVerificationError), @@ -54,14 +52,11 @@ pub enum VerificationError { #[derive(Clone, Debug, Decode, Encode, Eq, PartialEq, TypeInfo)] pub enum FraudProofStorageKeyRequest { - BlockRandomness, - Timestamp, + InvalidInherentExtrinsicData, SuccessfulBundles(DomainId), - TransactionByteFee, DomainAllowlistUpdates(DomainId), BlockDigest, RuntimeRegistry(RuntimeId), - DynamicCostOfStorage, DomainSudoCall(DomainId), MmrRoot(Number), } @@ -69,16 +64,15 @@ pub enum FraudProofStorageKeyRequest { impl FraudProofStorageKeyRequest { fn into_error(self, err: StorageProofVerificationError) -> VerificationError { match self { - Self::BlockRandomness => VerificationError::BlockRandomnessStorageProof(err), - Self::Timestamp => VerificationError::TimestampStorageProof(err), + Self::InvalidInherentExtrinsicData => { + VerificationError::InvalidInherentExtrinsicStorageProof(err) + } Self::SuccessfulBundles(_) => VerificationError::SuccessfulBundlesStorageProof(err), - Self::TransactionByteFee => VerificationError::TransactionByteFeeStorageProof(err), Self::DomainAllowlistUpdates(_) => { VerificationError::DomainAllowlistUpdatesStorageProof(err) } Self::BlockDigest => VerificationError::BlockDigestStorageProof(err), Self::RuntimeRegistry(_) => VerificationError::RuntimeRegistryStorageProof(err), - Self::DynamicCostOfStorage => VerificationError::DynamicCostOfStorageStorageProof(err), FraudProofStorageKeyRequest::DomainSudoCall(_) => { VerificationError::DomainSudoCallStorageProof(err) } @@ -173,17 +167,6 @@ impl BasicStorageProof for SuccessfulBundlesProof { } } -#[derive(Clone, Debug, Decode, Encode, Eq, PartialEq, TypeInfo)] -pub struct BlockRandomnessProof(StorageProof); - -impl_storage_proof!(BlockRandomnessProof); -impl BasicStorageProof for BlockRandomnessProof { - type StorageValue = Randomness; - fn storage_key_request(_key: Self::Key) -> FraudProofStorageKeyRequest> { - FraudProofStorageKeyRequest::BlockRandomness - } -} - #[derive(Clone, Debug, Decode, Encode, Eq, PartialEq, TypeInfo)] pub struct DomainChainsAllowlistUpdateStorageProof(StorageProof); @@ -196,39 +179,6 @@ impl BasicStorageProof for DomainChainsAllowlistUpdateStor } } -#[derive(Clone, Debug, Decode, Encode, Eq, PartialEq, TypeInfo)] -pub struct TimestampStorageProof(StorageProof); - -impl_storage_proof!(TimestampStorageProof); -impl BasicStorageProof for TimestampStorageProof { - type StorageValue = Moment; - fn storage_key_request(_key: Self::Key) -> FraudProofStorageKeyRequest> { - FraudProofStorageKeyRequest::Timestamp - } -} - -#[derive(Clone, Debug, Decode, Encode, Eq, PartialEq, TypeInfo)] -pub struct DynamicCostOfStorageProof(StorageProof); - -impl_storage_proof!(DynamicCostOfStorageProof); -impl BasicStorageProof for DynamicCostOfStorageProof { - type StorageValue = bool; - fn storage_key_request(_key: Self::Key) -> FraudProofStorageKeyRequest> { - FraudProofStorageKeyRequest::DynamicCostOfStorage - } -} - -#[derive(Clone, Debug, Decode, Encode, Eq, PartialEq, TypeInfo)] -pub struct ConsensusTransactionByteFeeProof(StorageProof); - -impl_storage_proof!(ConsensusTransactionByteFeeProof); -impl BasicStorageProof for ConsensusTransactionByteFeeProof { - type StorageValue = BlockTransactionByteFee; - fn storage_key_request(_key: Self::Key) -> FraudProofStorageKeyRequest> { - FraudProofStorageKeyRequest::TransactionByteFee - } -} - #[derive(Clone, Debug, Decode, Encode, Eq, PartialEq, TypeInfo)] pub struct BlockDigestProof(StorageProof); @@ -414,26 +364,48 @@ impl MaybeDomainRuntimeUpgradedProof { } #[derive(Clone, Debug, Decode, Encode, Eq, PartialEq, TypeInfo)] -pub struct InvalidInherentExtrinsicProof { - /// Block randomness storage proof - pub block_randomness_proof: BlockRandomnessProof, +pub struct InvalidInherentExtrinsicData { + /// Extrinsics shuffling seed, derived from block randomness + pub extrinsics_shuffling_seed: Randomness, - /// Block timestamp storage proof - pub timestamp_proof: TimestampStorageProof, + /// Block timestamp + pub timestamp: Moment, - /// Optional domain runtime code upgrade storage proof - pub maybe_domain_runtime_upgrade_proof: MaybeDomainRuntimeUpgradedProof, + /// Transaction byte fee, derived from dynamic cost of storage and the consensus chain byte fee + pub consensus_transaction_byte_fee: Balance, +} + +impl PassBy for InvalidInherentExtrinsicData { + type PassBy = pass_by::Codec; +} + +#[derive(Clone, Debug, Decode, Encode, Eq, PartialEq, TypeInfo)] +pub struct InvalidInherentExtrinsicDataProof(StorageProof); - /// Boolean indicating if dynamic cost of storage was used (but as a storage proof) - pub dynamic_cost_of_storage_proof: DynamicCostOfStorageProof, +impl_storage_proof!(InvalidInherentExtrinsicDataProof); +impl BasicStorageProof for InvalidInherentExtrinsicDataProof { + type StorageValue = InvalidInherentExtrinsicData; + fn storage_key_request(_key: Self::Key) -> FraudProofStorageKeyRequest> { + FraudProofStorageKeyRequest::InvalidInherentExtrinsicData + } +} - /// Transaction fee storage proof - pub consensus_chain_byte_fee_proof: ConsensusTransactionByteFeeProof, +#[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)] @@ -448,28 +420,12 @@ impl InvalidInherentExtrinsicProof { block_hash: Block::Hash, maybe_runtime_id: Option, ) -> Result { - let block_randomness_proof = - BlockRandomnessProof::generate(proof_provider, block_hash, (), storage_key_provider)?; - let timestamp_proof = - TimestampStorageProof::generate(proof_provider, block_hash, (), storage_key_provider)?; let maybe_domain_runtime_upgrade_proof = MaybeDomainRuntimeUpgradedProof::generate( storage_key_provider, proof_provider, block_hash, maybe_runtime_id, )?; - let dynamic_cost_of_storage_proof = DynamicCostOfStorageProof::generate( - proof_provider, - block_hash, - (), - storage_key_provider, - )?; - let consensus_chain_byte_fee_proof = ConsensusTransactionByteFeeProof::generate( - proof_provider, - block_hash, - (), - storage_key_provider, - )?; let domain_chain_allowlist_proof = DomainChainsAllowlistUpdateStorageProof::generate( proof_provider, block_hash, @@ -478,11 +434,7 @@ impl InvalidInherentExtrinsicProof { )?; Ok(Self { - block_randomness_proof, - timestamp_proof, maybe_domain_runtime_upgrade_proof, - dynamic_cost_of_storage_proof, - consensus_chain_byte_fee_proof, domain_chain_allowlist_proof, }) } @@ -492,42 +444,11 @@ impl InvalidInherentExtrinsicProof { domain_id: DomainId, runtime_id: RuntimeId, state_root: &Block::Hash, - ) -> Result { - let block_randomness = >::verify::( - self.block_randomness_proof.clone(), - (), - state_root, - )?; - - let timestamp = >::verify::( - self.timestamp_proof.clone(), - (), - state_root, - )?; - + ) -> Result { let maybe_domain_runtime_upgrade = self .maybe_domain_runtime_upgrade_proof .verify::(runtime_id, state_root)?; - let dynamic_cost_of_storage = - >::verify::( - self.dynamic_cost_of_storage_proof.clone(), - (), - state_root, - )?; - let consensus_transaction_byte_fee = if dynamic_cost_of_storage { - let raw_transaction_byte_fee = - >::verify::( - self.consensus_chain_byte_fee_proof.clone(), - (), - state_root, - )?; - - sp_domains::DOMAIN_STORAGE_FEE_MULTIPLIER * raw_transaction_byte_fee.next - } else { - Balance::from(1u32) - }; - let domain_chain_allowlist = >::verify::( self.domain_chain_allowlist_proof.clone(), @@ -535,14 +456,9 @@ impl InvalidInherentExtrinsicProof { state_root, )?; - Ok(DomainInherentExtrinsicData { - block_randomness, - timestamp, + Ok(InvalidInherentExtrinsicVerified { maybe_domain_runtime_upgrade, - consensus_transaction_byte_fee, domain_chain_allowlist, - // Populated by caller - maybe_sudo_runtime_call: None, }) } } diff --git a/crates/sp-domains-fraud-proof/src/verification.rs b/crates/sp-domains-fraud-proof/src/verification.rs index af8715cadb..6c4a624258 100644 --- a/crates/sp-domains-fraud-proof/src/verification.rs +++ b/crates/sp-domains-fraud-proof/src/verification.rs @@ -7,8 +7,8 @@ use crate::fraud_proof::{ }; use crate::storage_proof::{self, *}; use crate::{ - fraud_proof_runtime_interface, DomainInherentExtrinsic, DomainStorageKeyRequest, - StatelessDomainRuntimeCall, + fraud_proof_runtime_interface, DomainInherentExtrinsic, DomainInherentExtrinsicData, + DomainStorageKeyRequest, StatelessDomainRuntimeCall, }; #[cfg(not(feature = "std"))] use alloc::vec::Vec; @@ -17,7 +17,7 @@ use domain_runtime_primitives::BlockNumber; use hash_db::Hasher; use sp_core::storage::StorageKey; use sp_core::H256; -use sp_domains::extrinsics::{deduplicate_and_shuffle_extrinsics, extrinsics_shuffling_seed}; +use sp_domains::extrinsics::deduplicate_and_shuffle_extrinsics; use sp_domains::proof_provider_and_verifier::StorageProofVerifier; use sp_domains::valued_trie::valued_ordered_trie_root; use sp_domains::{ @@ -32,7 +32,7 @@ use sp_runtime::traits::{ use sp_runtime::{OpaqueExtrinsic, SaturatedConversion}; use sp_subspace_mmr::{ConsensusChainMmrLeafProof, MmrProofVerifier}; use sp_trie::{LayoutV1, StorageProof}; -use subspace_core_primitives::{Randomness, U256}; +use subspace_core_primitives::U256; use trie_db::node::Value; /// Verifies invalid domain extrinsic root fraud proof. @@ -65,24 +65,40 @@ where { let InvalidExtrinsicsRootProof { valid_bundle_digests, + invalid_inherent_extrinsic_proofs, invalid_inherent_extrinsic_proof, domain_sudo_call_proof, } = fraud_proof; - let mut domain_inherent_extrinsic_data = invalid_inherent_extrinsic_proof - .verify::(domain_id, runtime_id, &state_root)?; + let invalid_inherent_extrinsic_data = + >::verify::( + invalid_inherent_extrinsic_proofs.clone(), + (), + &state_root, + )?; + + let inherent_extrinsic_verified = invalid_inherent_extrinsic_proof.verify::( + domain_id, + runtime_id, + &state_root, + )?; let domain_sudo_call = >::verify::( domain_sudo_call_proof.clone(), domain_id, &state_root, )?; - domain_inherent_extrinsic_data.maybe_sudo_runtime_call = domain_sudo_call.maybe_call; - let shuffling_seed = H256::from_slice( - extrinsics_shuffling_seed::(domain_inherent_extrinsic_data.block_randomness) - .as_ref(), - ); + let shuffling_seed = invalid_inherent_extrinsic_data.extrinsics_shuffling_seed; + + let domain_inherent_extrinsic_data = DomainInherentExtrinsicData { + timestamp: invalid_inherent_extrinsic_data.timestamp, + maybe_domain_runtime_upgrade: inherent_extrinsic_verified.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, + maybe_sudo_runtime_call: domain_sudo_call.maybe_call, + }; let DomainInherentExtrinsic { domain_timestamp_extrinsic, @@ -115,10 +131,8 @@ where bundle_extrinsics_digests.extend(bundle_digest.bundle_digest.clone()); } - let mut ordered_extrinsics = deduplicate_and_shuffle_extrinsics( - bundle_extrinsics_digests, - Randomness::from(shuffling_seed.to_fixed_bytes()), - ); + let mut ordered_extrinsics = + deduplicate_and_shuffle_extrinsics(bundle_extrinsics_digests, shuffling_seed); // NOTE: the order of the inherent extrinsic MUST aligned with the // pallets order defined in `construct_runtime` macro for domains. diff --git a/crates/subspace-proof-of-space/Cargo.toml b/crates/subspace-proof-of-space/Cargo.toml index bf70fad3e0..fad67cf123 100644 --- a/crates/subspace-proof-of-space/Cargo.toml +++ b/crates/subspace-proof-of-space/Cargo.toml @@ -30,7 +30,6 @@ subspace-core-primitives = { version = "0.1.0", path = "../subspace-core-primiti [dev-dependencies] bitvec = "1.0.1" criterion = "0.5.1" -rand = "0.8.5" rayon = "1.10.0" [[bench]] diff --git a/crates/subspace-proof-of-space/src/lib.rs b/crates/subspace-proof-of-space/src/lib.rs index d4db08849a..448af40620 100644 --- a/crates/subspace-proof-of-space/src/lib.rs +++ b/crates/subspace-proof-of-space/src/lib.rs @@ -6,9 +6,7 @@ #![feature( array_chunks, array_windows, - const_trait_impl, generic_const_exprs, - int_roundings, portable_simd, step_trait )] diff --git a/crates/subspace-runtime/src/lib.rs b/crates/subspace-runtime/src/lib.rs index 76382a21ab..ce1bf5389d 100644 --- a/crates/subspace-runtime/src/lib.rs +++ b/crates/subspace-runtime/src/lib.rs @@ -836,6 +836,7 @@ impl pallet_domains::Config for Runtime { type Randomness = Subspace; type PalletId = DomainsPalletId; type StorageFee = TransactionFees; + type BlockTimestamp = pallet_timestamp::Pallet; type BlockSlot = BlockSlot; type BundleLongevity = BundleLongevity; type DomainsTransfersTracker = Transporter; @@ -1038,18 +1039,12 @@ pub struct StorageKeyProvider; impl FraudProofStorageKeyProvider> for StorageKeyProvider { fn storage_key(req: FraudProofStorageKeyRequest>) -> Vec { match req { - FraudProofStorageKeyRequest::BlockRandomness => { - pallet_subspace::BlockRandomness::::hashed_key().to_vec() - } - FraudProofStorageKeyRequest::Timestamp => { - pallet_timestamp::Now::::hashed_key().to_vec() + FraudProofStorageKeyRequest::InvalidInherentExtrinsicData => { + pallet_domains::BlockInvalidInherentExtrinsicData::::hashed_key().to_vec() } FraudProofStorageKeyRequest::SuccessfulBundles(domain_id) => { pallet_domains::SuccessfulBundles::::hashed_key_for(domain_id) } - FraudProofStorageKeyRequest::TransactionByteFee => { - TransactionFees::transaction_byte_fee_storage_key() - } FraudProofStorageKeyRequest::DomainAllowlistUpdates(domain_id) => { Messenger::domain_allow_list_update_storage_key(domain_id) } @@ -1057,9 +1052,6 @@ impl FraudProofStorageKeyProvider> for StorageKeyProvider { FraudProofStorageKeyRequest::RuntimeRegistry(runtime_id) => { pallet_domains::RuntimeRegistry::::hashed_key_for(runtime_id) } - FraudProofStorageKeyRequest::DynamicCostOfStorage => { - pallet_runtime_configs::EnableDynamicCostOfStorage::::hashed_key().to_vec() - } FraudProofStorageKeyRequest::DomainSudoCall(domain_id) => { pallet_domains::DomainSudoCalls::::hashed_key_for(domain_id) } diff --git a/crates/subspace-verification/src/lib.rs b/crates/subspace-verification/src/lib.rs index 434d3834c0..9a534d3905 100644 --- a/crates/subspace-verification/src/lib.rs +++ b/crates/subspace-verification/src/lib.rs @@ -25,6 +25,8 @@ extern crate alloc; #[cfg(not(feature = "std"))] use alloc::string::String; +#[cfg(all(feature = "kzg", not(feature = "std")))] +use alloc::vec::Vec; use codec::{Decode, Encode, MaxEncodedLen}; use core::mem; #[cfg(feature = "kzg")] diff --git a/domains/client/domain-operator/src/fraud_proof.rs b/domains/client/domain-operator/src/fraud_proof.rs index 7236273d35..3f82ba8eb7 100644 --- a/domains/client/domain-operator/src/fraud_proof.rs +++ b/domains/client/domain-operator/src/fraud_proof.rs @@ -382,6 +382,13 @@ where let maybe_runtime_id = self.is_domain_runtime_upgraded_at(domain_id, consensus_block_hash)?; + let invalid_inherent_extrinsic_proofs = InvalidInherentExtrinsicDataProof::generate( + self.consensus_client.as_ref(), + consensus_block_hash, + (), + &self.storage_key_provider, + )?; + let invalid_inherent_extrinsic_proof = InvalidInherentExtrinsicProof::generate( &self.storage_key_provider, self.consensus_client.as_ref(), @@ -404,6 +411,7 @@ where maybe_domain_runtime_code_proof, proof: FraudProofVariant::InvalidExtrinsicsRoot(InvalidExtrinsicsRootProof { valid_bundle_digests, + invalid_inherent_extrinsic_proofs, invalid_inherent_extrinsic_proof, domain_sudo_call_proof, }), diff --git a/shared/subspace-data-retrieval/src/object_fetcher.rs b/shared/subspace-data-retrieval/src/object_fetcher.rs index ed47611346..3744dd7b4d 100644 --- a/shared/subspace-data-retrieval/src/object_fetcher.rs +++ b/shared/subspace-data-retrieval/src/object_fetcher.rs @@ -514,13 +514,12 @@ where } } - // Padding at the end of segments can be skipped, it's not part of the object data - SegmentItem::Padding => {} + // Padding at the end of segments, and segment headers can be skipped, + // they're not part of the object data + SegmentItem::Padding | SegmentItem::ParentSegmentHeader(_) => {} // We should not see these items while collecting data for a single object - SegmentItem::Block { .. } - | SegmentItem::BlockStart { .. } - | SegmentItem::ParentSegmentHeader(_) => { + SegmentItem::Block { .. } | SegmentItem::BlockStart { .. } => { debug!( collected_data = ?data.len(), %segment_index, diff --git a/test/subspace-test-runtime/src/lib.rs b/test/subspace-test-runtime/src/lib.rs index b1bf2008d3..5da265a213 100644 --- a/test/subspace-test-runtime/src/lib.rs +++ b/test/subspace-test-runtime/src/lib.rs @@ -766,6 +766,7 @@ impl pallet_domains::Config for Runtime { type MinNominatorStake = MinNominatorStake; type PalletId = DomainsPalletId; type StorageFee = TransactionFees; + type BlockTimestamp = pallet_timestamp::Pallet; type BlockSlot = BlockSlot; type BundleLongevity = BundleLongevity; type DomainsTransfersTracker = Transporter; @@ -1115,18 +1116,12 @@ pub struct StorageKeyProvider; impl FraudProofStorageKeyProvider> for StorageKeyProvider { fn storage_key(req: FraudProofStorageKeyRequest>) -> Vec { match req { - FraudProofStorageKeyRequest::BlockRandomness => { - pallet_subspace::BlockRandomness::::hashed_key().to_vec() - } - FraudProofStorageKeyRequest::Timestamp => { - pallet_timestamp::Now::::hashed_key().to_vec() + FraudProofStorageKeyRequest::InvalidInherentExtrinsicData => { + pallet_domains::BlockInvalidInherentExtrinsicData::::hashed_key().to_vec() } FraudProofStorageKeyRequest::SuccessfulBundles(domain_id) => { pallet_domains::SuccessfulBundles::::hashed_key_for(domain_id) } - FraudProofStorageKeyRequest::TransactionByteFee => { - TransactionFees::transaction_byte_fee_storage_key() - } FraudProofStorageKeyRequest::DomainAllowlistUpdates(domain_id) => { Messenger::domain_allow_list_update_storage_key(domain_id) } @@ -1134,9 +1129,6 @@ impl FraudProofStorageKeyProvider> for StorageKeyProvider { FraudProofStorageKeyRequest::RuntimeRegistry(runtime_id) => { pallet_domains::RuntimeRegistry::::hashed_key_for(runtime_id) } - FraudProofStorageKeyRequest::DynamicCostOfStorage => { - pallet_runtime_configs::EnableDynamicCostOfStorage::::hashed_key().to_vec() - } FraudProofStorageKeyRequest::DomainSudoCall(domain_id) => { pallet_domains::DomainSudoCalls::::hashed_key_for(domain_id) }