From 945e9ab60185586286e65d588b90c9503c10c9ba Mon Sep 17 00:00:00 2001 From: vedhavyas Date: Mon, 9 Oct 2023 15:55:57 +0200 Subject: [PATCH] verify invalid domain extrinsic root --- Cargo.lock | 11 +- crates/pallet-domains/Cargo.toml | 2 + crates/pallet-domains/src/lib.rs | 31 ++--- crates/pallet-domains/src/tests.rs | 110 +++++++----------- crates/sp-domains-fraud-proof/Cargo.toml | 12 +- .../src/host_functions.rs | 61 ++++++++-- crates/sp-domains-fraud-proof/src/lib.rs | 3 +- .../src/runtime_interface.rs | 4 +- .../src/verification.rs | 91 +++++++++++++++ crates/sp-domains/Cargo.toml | 10 +- crates/sp-domains/src/fraud_proof.rs | 22 +--- crates/sp-domains/src/lib.rs | 12 +- crates/sp-domains/src/verification.rs | 102 +--------------- crates/subspace-runtime/src/lib.rs | 34 +----- crates/subspace-service/src/lib.rs | 48 +++++--- .../block-preprocessor/src/inherents.rs | 9 +- .../block-preprocessor/src/runtime_api.rs | 2 +- .../src/runtime_api_full.rs | 2 +- .../src/runtime_api_light.rs | 2 +- .../client/domain-operator/src/fraud_proof.rs | 17 --- domains/primitives/runtime/src/lib.rs | 2 +- domains/runtime/evm/src/lib.rs | 10 +- domains/test/runtime/evm/src/lib.rs | 10 +- test/subspace-test-runtime/src/lib.rs | 34 +----- test/subspace-test-service/src/lib.rs | 39 +++++-- 25 files changed, 310 insertions(+), 370 deletions(-) create mode 100644 crates/sp-domains-fraud-proof/src/verification.rs diff --git a/Cargo.lock b/Cargo.lock index 1f66a40c464..1315892e166 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7237,6 +7237,7 @@ dependencies = [ "scale-info", "sp-core", "sp-domains", + "sp-domains-fraud-proof", "sp-externalities", "sp-io", "sp-runtime", @@ -10834,7 +10835,6 @@ dependencies = [ name = "sp-domains" version = "0.1.0" dependencies = [ - "async-trait", "blake2", "domain-runtime-primitives", "frame-support", @@ -10852,10 +10852,8 @@ dependencies = [ "sp-blockchain", "sp-consensus-slots", "sp-core", - "sp-externalities", - "sp-inherents", - "sp-keystore", "sp-runtime", + "sp-runtime-interface", "sp-state-machine", "sp-std", "sp-trie", @@ -10870,16 +10868,21 @@ dependencies = [ name = "sp-domains-fraud-proof" version = "0.1.0" dependencies = [ + "domain-block-preprocessor", + "hash-db 0.16.0", "parity-scale-codec", "scale-info", "sp-api", "sp-blockchain", "sp-core", + "sp-domains", "sp-externalities", "sp-runtime", "sp-runtime-interface", "sp-std", + "sp-trie", "subspace-core-primitives", + "trie-db", ] [[package]] diff --git a/crates/pallet-domains/Cargo.toml b/crates/pallet-domains/Cargo.toml index 86876277d82..fd7deafbfcf 100644 --- a/crates/pallet-domains/Cargo.toml +++ b/crates/pallet-domains/Cargo.toml @@ -20,6 +20,7 @@ log = { version = "0.4.20", default-features = false } scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "c90d6edfd8c63168eff0dce6f2ace4d66dd139f7" } sp-domains = { version = "0.1.0", default-features = false, path = "../sp-domains" } +sp-domains-fraud-proof = { version = "0.1.0", default-features = false, path = "../sp-domains-fraud-proof" } sp-io = { version = "23.0.0", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "c90d6edfd8c63168eff0dce6f2ace4d66dd139f7" } sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "c90d6edfd8c63168eff0dce6f2ace4d66dd139f7" } sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "c90d6edfd8c63168eff0dce6f2ace4d66dd139f7" } @@ -45,6 +46,7 @@ std = [ "scale-info/std", "sp-core/std", "sp-domains/std", + "sp-domains-fraud-proof/std", "sp-io/std", "sp-runtime/std", "sp-std/std", diff --git a/crates/pallet-domains/src/lib.rs b/crates/pallet-domains/src/lib.rs index 838402cfa77..13ea955a02b 100644 --- a/crates/pallet-domains/src/lib.rs +++ b/crates/pallet-domains/src/lib.rs @@ -46,14 +46,14 @@ use scale_info::TypeInfo; use sp_core::H256; use sp_domains::bundle_producer_election::{is_below_threshold, BundleProducerElectionParams}; use sp_domains::fraud_proof::{FraudProof, InvalidTotalRewardsProof}; -use sp_domains::verification::{ - verify_invalid_domain_extrinsics_root_fraud_proof, verify_invalid_total_rewards_fraud_proof, -}; +use sp_domains::verification::verify_invalid_total_rewards_fraud_proof; use sp_domains::{ DomainBlockLimit, DomainId, DomainInstanceData, ExecutionReceipt, OpaqueBundle, OperatorId, OperatorPublicKey, ProofOfElection, RuntimeId, DOMAIN_EXTRINSICS_SHUFFLING_SEED_SUBJECT, EMPTY_EXTRINSIC_ROOT, }; +use sp_domains_fraud_proof::fraud_proof_runtime_interface::get_invalid_domain_extrinsic_root_info; +use sp_domains_fraud_proof::verification::verify_invalid_domain_extrinsics_root_fraud_proof; use sp_runtime::traits::{BlakeTwo256, CheckedSub, Hash, One, Zero}; use sp_runtime::{RuntimeAppPublic, SaturatedConversion, Saturating}; use sp_std::boxed::Box; @@ -141,7 +141,7 @@ mod pallet { use frame_support::{Identity, PalletError}; use frame_system::pallet_prelude::*; use sp_core::H256; - use sp_domains::fraud_proof::{DeriveExtrinsics, FraudProof, StorageKeys}; + use sp_domains::fraud_proof::FraudProof; use sp_domains::transaction::InvalidTransactionCode; use sp_domains::{ BundleDigest, DomainId, EpochIndex, GenesisDomain, OperatorId, ReceiptHash, RuntimeId, @@ -159,7 +159,6 @@ mod pallet { use sp_std::vec; use sp_std::vec::Vec; use subspace_core_primitives::U256; - use subspace_runtime_primitives::Moment; #[pallet::config] pub trait Config: frame_system::Config { @@ -287,12 +286,6 @@ mod pallet { /// Randomness source. type Randomness: RandomnessT>; - - /// Trait impl to fetch storage keys. - type StorageKeys: StorageKeys; - - /// Derive extrinsics trait impl. - type DeriveExtrinsics: DeriveExtrinsics; } #[pallet::pallet] @@ -590,10 +583,10 @@ mod pallet { DescendantsOfFraudulentERNotPruned, /// Invalid fraud proof since total rewards are not mismatched. InvalidTotalRewardsFraudProof(sp_domains::verification::VerificationError), - /// Missing state root for a given consensus block - MissingConsensusStateRoot, /// Invalid domain extrinsic fraud proof InvalidExtrinsicRootFraudProof(sp_domains::verification::VerificationError), + /// Failed to get invalid domain extrinsic verification info. + FailedToGetInvalidDomainExtrinsicRootVerificationInfo, } impl From for Error { @@ -1497,11 +1490,12 @@ impl Pallet { .map_err(FraudProofError::InvalidTotalRewardsFraudProof)?; } FraudProof::InvalidExtrinsicsRoot(proof) => { - let consensus_state_root = ConsensusBlockHash::::get( + let consensus_block_hash = bad_receipt.consensus_block_hash; + let verification_info = get_invalid_domain_extrinsic_root_info( + H256::from_slice(consensus_block_hash.as_ref()), proof.domain_id, - bad_receipt.consensus_block_number, ) - .ok_or(FraudProofError::MissingConsensusStateRoot)?; + .ok_or(FraudProofError::FailedToGetInvalidDomainExtrinsicRootVerificationInfo)?; verify_invalid_domain_extrinsics_root_fraud_proof::< T::Block, @@ -1509,9 +1503,8 @@ impl Pallet { T::DomainHash, BalanceOf, T::Hashing, - T::StorageKeys, - T::DeriveExtrinsics, - >(consensus_state_root, bad_receipt, proof) + T::DomainHashing, + >(bad_receipt, proof, verification_info) .map_err(FraudProofError::InvalidExtrinsicRootFraudProof)?; } _ => {} diff --git a/crates/pallet-domains/src/tests.rs b/crates/pallet-domains/src/tests.rs index cc0e7edc0c0..b1c72fcb316 100644 --- a/crates/pallet-domains/src/tests.rs +++ b/crates/pallet-domains/src/tests.rs @@ -7,7 +7,6 @@ use crate::{ }; use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::dispatch::RawOrigin; -use frame_support::storage::generator::StorageValue; use frame_support::traits::{ConstU16, ConstU32, ConstU64, Currency, Hooks}; use frame_support::weights::Weight; use frame_support::{assert_err, assert_ok, parameter_types, PalletId}; @@ -27,10 +26,14 @@ use sp_domains::{ OperatorPair, ProofOfElection, ReceiptHash, RuntimeType, SealedBundleHeader, StakingHoldIdentifier, }; +use sp_domains_fraud_proof::{ + FraudProofExtension, FraudProofHostFunctions, InvalidDomainExtrinsicRootInfo, +}; use sp_runtime::traits::{AccountIdConversion, BlakeTwo256, Hash as HashT, IdentityLookup, Zero}; use sp_runtime::{BuildStorage, OpaqueExtrinsic}; use sp_state_machine::backend::AsTrieBackend; use sp_state_machine::{prove_read, Backend, TrieBackendBuilder}; +use sp_std::sync::Arc; use sp_trie::trie_types::TrieDBMutBuilderV1; use sp_trie::{PrefixedMemoryDB, StorageProof, TrieMut}; use sp_version::RuntimeVersion; @@ -193,20 +196,6 @@ impl frame_support::traits::Randomness for MockRandomness { } } -pub struct StorageKeys; -impl sp_domains::fraud_proof::StorageKeys for StorageKeys { - fn block_randomness_storage_key() -> StorageKey { - StorageKey( - frame_support::storage::storage_prefix("Subspace".as_ref(), "BlockRandomness".as_ref()) - .to_vec(), - ) - } - - fn timestamp_storage_key() -> StorageKey { - StorageKey(pallet_timestamp::pallet::Now::::storage_value_final_key().to_vec()) - } -} - const SLOT_DURATION: u64 = 1000; impl pallet_timestamp::Config for Test { /// A timestamp: milliseconds since the unix epoch. @@ -216,14 +205,6 @@ impl pallet_timestamp::Config for Test { type WeightInfo = (); } -pub struct DeriveExtrinsics; -impl sp_domains::fraud_proof::DeriveExtrinsics for DeriveExtrinsics { - fn derive_timestamp_extrinsic(now: Moment) -> Vec { - UncheckedExtrinsic::new_unsigned(pallet_timestamp::Call::::set { now }.into()) - .encode() - } -} - impl pallet_domains::Config for Test { type RuntimeEvent = RuntimeEvent; type DomainNumber = BlockNumber; @@ -249,8 +230,6 @@ impl pallet_domains::Config for Test { type TreasuryAccount = TreasuryAccount; type MaxPendingStakingOperation = MaxPendingStakingOperation; type Randomness = MockRandomness; - type StorageKeys = StorageKeys; - type DeriveExtrinsics = DeriveExtrinsics; } pub(crate) fn new_test_ext() -> sp_io::TestExternalities { @@ -261,6 +240,24 @@ pub(crate) fn new_test_ext() -> sp_io::TestExternalities { t.into() } +pub(crate) struct MockDomainFraudProofExtension(Randomness, Moment); + +impl FraudProofHostFunctions for MockDomainFraudProofExtension { + fn get_invalid_domain_extrinsic_root_info( + &self, + _consensus_block_hash: H256, + _domain_id: DomainId, + ) -> Option { + Some(InvalidDomainExtrinsicRootInfo { + block_randomness: self.0, + timestamp_extrinsic: UncheckedExtrinsic::new_unsigned( + pallet_timestamp::Call::::set { now: self.1 }.into(), + ) + .encode(), + }) + } +} + pub(crate) fn new_test_ext_with_extensions() -> sp_io::TestExternalities { let version = RuntimeVersion { spec_name: "test".into(), @@ -842,13 +839,12 @@ fn storage_proof_for_key + AsTrieBackend(domain_id, bad_receipt_at).unwrap(); let bad_receipt_hash = domain_block.execution_receipt.hash(); - let (fraud_proof, _root) = generate_invalid_domain_extrinsic_root_fraud_proof::( - domain_id, - bad_receipt_hash, - Randomness::from([1u8; 32]), - 1000, - ); + let fraud_proof = + generate_invalid_domain_extrinsic_root_fraud_proof::(domain_id, bad_receipt_hash); let (consensus_block_number, consensus_block_hash) = ( domain_block.execution_receipt.consensus_block_number, domain_block.execution_receipt.consensus_block_hash, ); ConsensusBlockHash::::insert(domain_id, consensus_block_number, consensus_block_hash); DomainBlocks::::insert(bad_receipt_hash, domain_block); - assert_ok!(Domains::validate_fraud_proof(&fraud_proof),); + fraud_proof }); + + let fraud_proof_ext = FraudProofExtension::new(Arc::new(MockDomainFraudProofExtension( + Randomness::from([1u8; 32]), + 1000, + ))); + ext.register_extension(fraud_proof_ext); + + ext.execute_with(|| { + assert_ok!(Domains::validate_fraud_proof(&fraud_proof),); + }) } fn generate_invalid_domain_extrinsic_root_fraud_proof( domain_id: DomainId, bad_receipt_hash: ReceiptHash, - randomness: Randomness, - moment: Moment, -) -> (FraudProof, T::Hash>, T::Hash) { - let randomness_storage_key = - frame_support::storage::storage_prefix("Subspace".as_ref(), "BlockRandomness".as_ref()) - .to_vec(); - let timestamp_storage_key = - pallet_timestamp::pallet::Now::::storage_value_final_key().to_vec(); - let mut root = T::Hash::default(); - let mut mdb = PrefixedMemoryDB::::default(); - { - let mut trie = TrieDBMutBuilderV1::new(&mut mdb, &mut root).build(); - trie.insert(&randomness_storage_key, &randomness.encode()) - .unwrap(); - trie.insert(×tamp_storage_key, &moment.encode()) - .unwrap(); - }; - - let backend = TrieBackendBuilder::new(mdb, root).build(); - let (_, randomness_storage_proof) = - storage_proof_for_key::(backend.clone(), StorageKey(randomness_storage_key)); - let (root, timestamp_storage_proof) = - storage_proof_for_key::(backend, StorageKey(timestamp_storage_key)); +) -> FraudProof, T::Hash> { let valid_bundle_digests = vec![ValidBundleDigest { bundle_index: 0, bundle_digest: vec![(Some(vec![1, 2, 3]), ExtrinsicDigest::Data(vec![4, 5, 6]))], }]; - ( - FraudProof::InvalidExtrinsicsRoot(InvalidExtrinsicsRootProof { - domain_id, - bad_receipt_hash, - randomness_storage_proof, - valid_bundle_digests, - timestamp_storage_proof, - }), - root, - ) + + FraudProof::InvalidExtrinsicsRoot(InvalidExtrinsicsRootProof { + domain_id, + bad_receipt_hash, + valid_bundle_digests, + }) } #[test] diff --git a/crates/sp-domains-fraud-proof/Cargo.toml b/crates/sp-domains-fraud-proof/Cargo.toml index 64196a8f4ea..74d6da9e8b5 100644 --- a/crates/sp-domains-fraud-proof/Cargo.toml +++ b/crates/sp-domains-fraud-proof/Cargo.toml @@ -12,28 +12,38 @@ include = [ [dependencies] codec = { package = "parity-scale-codec", version = "3.6.5", default-features = false, features = ["derive"] } +hash-db = { version = "0.16.0", default-features = false } scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } +domain-block-preprocessor = { version = "0.1.0", default-features = false, path = "../../domains/client/block-preprocessor", optional = true } sp-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "c90d6edfd8c63168eff0dce6f2ace4d66dd139f7" } sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/polkadot-sdk", rev = "c90d6edfd8c63168eff0dce6f2ace4d66dd139f7", optional = true } sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "c90d6edfd8c63168eff0dce6f2ace4d66dd139f7" } +sp-domains = { version = "0.1.0", default-features = false, path = "../sp-domains" } sp-externalities = { version = "0.19.0", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "c90d6edfd8c63168eff0dce6f2ace4d66dd139f7" } sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "c90d6edfd8c63168eff0dce6f2ace4d66dd139f7" } sp-runtime-interface = { version = "17.0.0", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "c90d6edfd8c63168eff0dce6f2ace4d66dd139f7" } sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "c90d6edfd8c63168eff0dce6f2ace4d66dd139f7" } +sp-trie = { version = "22.0.0", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "c90d6edfd8c63168eff0dce6f2ace4d66dd139f7" } subspace-core-primitives = { version = "0.1.0", default-features = false, path = "../subspace-core-primitives" } +trie-db = { version = "0.28.0", default-features = false } [features] default = ["std"] std = [ "codec/std", + "hash-db/std", "scale-info/std", + "domain-block-preprocessor", "sp-api/std", "sp-blockchain", "sp-core/std", + "sp-domains/std", "sp-externalities/std", "sp-runtime/std", "sp-runtime-interface/std", "sp-std/std", - "subspace-core-primitives/std" + "sp-trie/std", + "subspace-core-primitives/std", + "trie-db/std" ] runtime-benchmarks = [] diff --git a/crates/sp-domains-fraud-proof/src/host_functions.rs b/crates/sp-domains-fraud-proof/src/host_functions.rs index 94e61d4370f..07c0b7cb06c 100644 --- a/crates/sp-domains-fraud-proof/src/host_functions.rs +++ b/crates/sp-domains-fraud-proof/src/host_functions.rs @@ -1,7 +1,13 @@ use crate::InvalidDomainExtrinsicRootInfo; -use sp_api::BlockT; +use codec::Encode; +use domain_block_preprocessor::runtime_api::InherentExtrinsicConstructor; +use domain_block_preprocessor::runtime_api_light::RuntimeApiLight; +use sp_api::{BlockT, ProvideRuntimeApi}; use sp_blockchain::HeaderBackend; +use sp_core::traits::CodeExecutor; use sp_core::H256; +use sp_domains::{DomainId, DomainsApi}; +use sp_runtime::traits::NumberFor; use std::marker::PhantomData; use std::sync::Arc; @@ -11,6 +17,7 @@ pub trait FraudProofHostFunctions: Send + Sync { fn get_invalid_domain_extrinsic_root_info( &self, consensus_block_hash: H256, + domain_id: DomainId, ) -> Option; } @@ -27,35 +34,65 @@ impl FraudProofExtension { } /// Trait Impl to query and verify Domains Fraud proof. -#[allow(dead_code)] -pub struct FraudProofHostFunctionsImpl { +pub struct FraudProofHostFunctionsImpl { consensus_client: Arc, - _phantom: PhantomData, + executor: Arc, + _phantom: PhantomData<(Block, DomainBlock)>, } -impl FraudProofHostFunctionsImpl { - pub fn new(consensus_client: Arc) -> Self { +impl + FraudProofHostFunctionsImpl +{ + pub fn new(consensus_client: Arc, executor: Arc) -> Self { FraudProofHostFunctionsImpl { consensus_client, + executor, _phantom: Default::default(), } } } -impl FraudProofHostFunctions for FraudProofHostFunctionsImpl +impl FraudProofHostFunctions + for FraudProofHostFunctionsImpl where Block: BlockT, Block::Hash: From, - Client: HeaderBackend, + DomainBlock: BlockT, + Client: HeaderBackend + ProvideRuntimeApi, + Client::Api: DomainsApi, DomainBlock::Hash>, + Executor: CodeExecutor, { fn get_invalid_domain_extrinsic_root_info( &self, - _consensus_block_hash: H256, + consensus_block_hash: H256, + domain_id: DomainId, ) -> Option { - // TODO: will update in the following commits. + let runtime_api = self.consensus_client.runtime_api(); + let consensus_block_hash = consensus_block_hash.into(); + let runtime_code = runtime_api + .domain_runtime_code(consensus_block_hash, domain_id) + .ok()??; + let block_randomness = runtime_api + .extrinsics_shuffling_seed(consensus_block_hash) + .ok()?; + let timestamp = runtime_api.timestamp(consensus_block_hash).ok()?; + + let domain_runtime_api_light = + RuntimeApiLight::new(self.executor.clone(), runtime_code.into()); + + let timestamp_extrinsic = + InherentExtrinsicConstructor::::construct_timestamp_inherent_extrinsic( + &domain_runtime_api_light, + // We do not care about the domain hash since this is stateless call into + // domain runtime, + Default::default(), + timestamp, + ) + .ok()? + .encode(); Some(InvalidDomainExtrinsicRootInfo { - block_randomness: Default::default(), - timestamp_extrinsic: vec![], + block_randomness, + timestamp_extrinsic, }) } } diff --git a/crates/sp-domains-fraud-proof/src/lib.rs b/crates/sp-domains-fraud-proof/src/lib.rs index bdf8b9aebbe..1dde2e1cfc2 100644 --- a/crates/sp-domains-fraud-proof/src/lib.rs +++ b/crates/sp-domains-fraud-proof/src/lib.rs @@ -20,13 +20,14 @@ #[cfg(feature = "std")] mod host_functions; mod runtime_interface; +pub mod verification; use codec::{Decode, Encode}; #[cfg(feature = "std")] pub use host_functions::{ FraudProofExtension, FraudProofHostFunctions, FraudProofHostFunctionsImpl, }; -pub use runtime_interface::fraud_proof_runtime_interface::get_invalid_domain_extrinsic_root_info; +pub use runtime_interface::fraud_proof_runtime_interface; #[cfg(feature = "std")] pub use runtime_interface::fraud_proof_runtime_interface::HostFunctions; use sp_api::scale_info::TypeInfo; diff --git a/crates/sp-domains-fraud-proof/src/runtime_interface.rs b/crates/sp-domains-fraud-proof/src/runtime_interface.rs index f9b8b8d2b42..7ae5651aef5 100644 --- a/crates/sp-domains-fraud-proof/src/runtime_interface.rs +++ b/crates/sp-domains-fraud-proof/src/runtime_interface.rs @@ -2,6 +2,7 @@ use crate::FraudProofExtension; use crate::InvalidDomainExtrinsicRootInfo; use sp_core::H256; +use sp_domains::DomainId; #[cfg(feature = "std")] use sp_externalities::ExternalitiesExt; use sp_runtime_interface::runtime_interface; @@ -12,9 +13,10 @@ pub trait FraudProofRuntimeInterface { fn get_invalid_domain_extrinsic_root_info( &mut self, consensus_block_hash: H256, + domain_id: DomainId, ) -> Option { self.extension::() .expect("No `FraudProofExtension` associated for the current context!") - .get_invalid_domain_extrinsic_root_info(consensus_block_hash) + .get_invalid_domain_extrinsic_root_info(consensus_block_hash, domain_id) } } diff --git a/crates/sp-domains-fraud-proof/src/verification.rs b/crates/sp-domains-fraud-proof/src/verification.rs new file mode 100644 index 00000000000..669098a2ae0 --- /dev/null +++ b/crates/sp-domains-fraud-proof/src/verification.rs @@ -0,0 +1,91 @@ +use crate::InvalidDomainExtrinsicRootInfo; +use hash_db::Hasher; +use sp_core::H256; +use sp_domains::fraud_proof::{ExtrinsicDigest, InvalidExtrinsicsRootProof}; +use sp_domains::valued_trie_root::valued_ordered_trie_root; +use sp_domains::verification::{ + deduplicate_and_shuffle_extrinsics, extrinsics_shuffling_seed, VerificationError, +}; +use sp_domains::ExecutionReceipt; +use sp_runtime::traits::{BlakeTwo256, Block, Hash, NumberFor}; +use sp_std::vec::Vec; +use sp_trie::LayoutV1; +use subspace_core_primitives::Randomness; +use trie_db::node::Value; + +pub fn verify_invalid_domain_extrinsics_root_fraud_proof< + CBlock, + DomainNumber, + DomainHash, + Balance, + Hashing, + DomainHashing, +>( + bad_receipt: ExecutionReceipt< + NumberFor, + CBlock::Hash, + DomainNumber, + DomainHash, + Balance, + >, + fraud_proof: &InvalidExtrinsicsRootProof, + verification_info: InvalidDomainExtrinsicRootInfo, +) -> Result<(), VerificationError> +where + CBlock: Block, + Hashing: Hasher, + DomainHashing: Hasher, + DomainHash: Into, +{ + let InvalidExtrinsicsRootProof { + valid_bundle_digests, + .. + } = fraud_proof; + + let InvalidDomainExtrinsicRootInfo { + block_randomness, + timestamp_extrinsic, + } = verification_info; + + let mut bundle_extrinsics_digests = Vec::new(); + for (valid_bundle, bundle_digest) in bad_receipt + .valid_bundles + .into_iter() + .zip(valid_bundle_digests) + { + let bundle_digest_hash = BlakeTwo256::hash_of(&bundle_digest.bundle_digest); + if bundle_digest_hash != valid_bundle.bundle_digest_hash { + return Err(VerificationError::InvalidBundleDigest); + } + + bundle_extrinsics_digests.extend(bundle_digest.bundle_digest.clone()); + } + + let shuffling_seed = + H256::from_slice(extrinsics_shuffling_seed::(block_randomness).as_ref()); + + let mut ordered_extrinsics = deduplicate_and_shuffle_extrinsics( + bundle_extrinsics_digests, + Randomness::from(shuffling_seed.to_fixed_bytes()), + ); + + let timestamp_extrinsic = ExtrinsicDigest::new::>(timestamp_extrinsic); + ordered_extrinsics.insert(0, timestamp_extrinsic); + + let ordered_trie_node_values = ordered_extrinsics + .iter() + .map(|ext_digest| match ext_digest { + ExtrinsicDigest::Data(data) => Value::Inline(data), + ExtrinsicDigest::Hash(hash) => Value::Node(hash.0.as_slice()), + }) + .collect(); + + // TODO: domain runtime upgrade extrinsic + let extrinsics_root = + valued_ordered_trie_root::>(ordered_trie_node_values); + if bad_receipt.domain_block_extrinsic_root == extrinsics_root { + return Err(VerificationError::InvalidProof); + } + + Ok(()) +} diff --git a/crates/sp-domains/Cargo.toml b/crates/sp-domains/Cargo.toml index b7418bd7d9e..6249defbdb8 100644 --- a/crates/sp-domains/Cargo.toml +++ b/crates/sp-domains/Cargo.toml @@ -12,7 +12,6 @@ description = "Primitives of domains pallet" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -async-trait = { version = "0.1.73", optional = true } blake2 = { version = "0.10.6", default-features = false } domain-runtime-primitives = { version = "0.1.0", default-features = false, path = "../../domains/primitives/runtime" } frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "c90d6edfd8c63168eff0dce6f2ace4d66dd139f7" } @@ -29,10 +28,8 @@ sp-application-crypto = { version = "23.0.0", default-features = false, git = "h sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/polkadot-sdk", rev = "c90d6edfd8c63168eff0dce6f2ace4d66dd139f7", optional = true } sp-consensus-slots = { version = "0.10.0-dev", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "c90d6edfd8c63168eff0dce6f2ace4d66dd139f7" } sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "c90d6edfd8c63168eff0dce6f2ace4d66dd139f7" } -sp-externalities = { version = "0.19.0", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "c90d6edfd8c63168eff0dce6f2ace4d66dd139f7" } -sp-inherents = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "c90d6edfd8c63168eff0dce6f2ace4d66dd139f7" } -sp-keystore = { version = "0.27.0", git = "https://github.com/subspace/polkadot-sdk", rev = "c90d6edfd8c63168eff0dce6f2ace4d66dd139f7", optional = true } sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "c90d6edfd8c63168eff0dce6f2ace4d66dd139f7" } +sp-runtime-interface = { version = "17.0.0", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "c90d6edfd8c63168eff0dce6f2ace4d66dd139f7" } sp-state-machine = { version = "0.28.0", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "c90d6edfd8c63168eff0dce6f2ace4d66dd139f7" } sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "c90d6edfd8c63168eff0dce6f2ace4d66dd139f7" } sp-trie = { version = "22.0.0", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "c90d6edfd8c63168eff0dce6f2ace4d66dd139f7" } @@ -49,7 +46,6 @@ rand = { version = "0.8.5", features = ["min_const_gen"] } [features] default = ["std"] std = [ - "async-trait", "blake2/std", "domain-runtime-primitives/std", "frame-support/std", @@ -65,10 +61,8 @@ std = [ "sp-application-crypto/std", "sp-consensus-slots/std", "sp-core/std", - "sp-externalities/std", - "sp-inherents/std", - "sp-keystore", "sp-runtime/std", + "sp-runtime-interface/std", "sp-state-machine/std", "sp-std/std", "sp-trie/std", diff --git a/crates/sp-domains/src/fraud_proof.rs b/crates/sp-domains/src/fraud_proof.rs index 7300d62b117..54507a448ba 100644 --- a/crates/sp-domains/src/fraud_proof.rs +++ b/crates/sp-domains/src/fraud_proof.rs @@ -3,7 +3,6 @@ use hash_db::Hasher; use parity_scale_codec::{Decode, Encode}; use scale_info::TypeInfo; use sp_consensus_slots::Slot; -use sp_core::storage::StorageKey; use sp_core::H256; use sp_runtime::traits::{BlakeTwo256, Hash as HashT, Header as HeaderT}; use sp_std::vec::Vec; @@ -70,12 +69,6 @@ impl ExecutionPhase { } } -/// Trait to derive domain extrinsics such as timestamp on Consensus chain. -pub trait DeriveExtrinsics { - /// Derives pallet_timestamp::set extrinsic. - fn derive_timestamp_extrinsic(moment: Moment) -> Vec; -} - /// Error type of fraud proof verification on consensus node. #[derive(Debug)] #[cfg_attr(feature = "thiserror", derive(thiserror::Error))] @@ -436,11 +429,12 @@ pub enum ExtrinsicDigest { impl ExtrinsicDigest { pub fn new(ext: Vec) -> Self where - Layout::Hash: Hasher, + Layout::Hash: Hasher, + ::Out: Into, { if let Some(threshold) = Layout::MAX_INLINE_VALUE { if ext.len() >= threshold as usize { - ExtrinsicDigest::Hash(Layout::Hash::hash(&ext)) + ExtrinsicDigest::Hash(Layout::Hash::hash(&ext).into()) } else { ExtrinsicDigest::Data(ext) } @@ -471,10 +465,6 @@ pub struct InvalidExtrinsicsRootProof { pub bad_receipt_hash: ReceiptHash, /// Valid Bundle digests pub valid_bundle_digests: Vec, - /// Randomness Storage proof - pub randomness_storage_proof: StorageProof, - /// Timestamp Storage proof - pub timestamp_storage_proof: StorageProof, } impl InvalidTotalRewardsProof { @@ -487,12 +477,6 @@ impl InvalidTotalRewardsProof { } } -/// Trait to get Storage keys. -pub trait StorageKeys { - fn block_randomness_storage_key() -> StorageKey; - fn timestamp_storage_key() -> StorageKey; -} - /// This is a representation of actual Block Rewards storage in pallet-operator-rewards. /// Any change in key or value there should be changed here accordingly. pub fn operator_block_rewards_final_key() -> Vec { diff --git a/crates/sp-domains/src/lib.rs b/crates/sp-domains/src/lib.rs index 25ae0b899c9..f392f681dc6 100644 --- a/crates/sp-domains/src/lib.rs +++ b/crates/sp-domains/src/lib.rs @@ -47,6 +47,8 @@ use sp_runtime::traits::{ BlakeTwo256, Block as BlockT, CheckedAdd, Hash as HashT, NumberFor, Zero, }; use sp_runtime::{DigestItem, OpaqueExtrinsic, Percent}; +use sp_runtime_interface::pass_by; +use sp_runtime_interface::pass_by::PassBy; use sp_std::vec::Vec; use sp_weights::Weight; use subspace_core_primitives::crypto::blake2b_256_hash; @@ -163,6 +165,10 @@ impl DomainId { } } +impl PassBy for DomainId { + type PassBy = pass_by::Codec; +} + #[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone)] pub struct BundleHeader { /// Proof of bundle producer election. @@ -760,12 +766,6 @@ sp_api::decl_runtime_apis! { /// Returns the chain state root at the given block. fn domain_state_root(domain_id: DomainId, number: DomainNumber, hash: DomainHash) -> Option; - - /// Returns the storage key for block randomness. - fn block_randomness_storage_key() -> Vec; - - /// Returns the storage key for timestamp; - fn timestamp_storage_key() -> Vec; } pub trait BundleProducerElectionApi { diff --git a/crates/sp-domains/src/verification.rs b/crates/sp-domains/src/verification.rs index 8bb55aaee9f..4658a06aad4 100644 --- a/crates/sp-domains/src/verification.rs +++ b/crates/sp-domains/src/verification.rs @@ -1,7 +1,3 @@ -use crate::fraud_proof::{ - DeriveExtrinsics, ExtrinsicDigest, InvalidExtrinsicsRootProof, StorageKeys, -}; -use crate::valued_trie_root::valued_ordered_trie_root; use crate::{ExecutionReceipt, DOMAIN_EXTRINSICS_SHUFFLING_SEED_SUBJECT}; use domain_runtime_primitives::opaque::AccountId; use frame_support::PalletError; @@ -12,8 +8,7 @@ use rand::SeedableRng; use rand_chacha::ChaCha8Rng; use scale_info::TypeInfo; use sp_core::storage::StorageKey; -use sp_core::H256; -use sp_runtime::traits::{BlakeTwo256, Block, Hash, NumberFor}; +use sp_runtime::traits::{Block, NumberFor}; use sp_state_machine::trace; use sp_std::collections::btree_map::BTreeMap; use sp_std::collections::vec_deque::VecDeque; @@ -22,8 +17,6 @@ use sp_std::marker::PhantomData; use sp_std::vec::Vec; use sp_trie::{read_trie_value, LayoutV1, StorageProof}; use subspace_core_primitives::Randomness; -use subspace_runtime_primitives::Moment; -use trie_db::node::Value; /// Verification error. #[derive(Debug, PartialEq, Eq, Encode, Decode, PalletError, TypeInfo)] @@ -100,98 +93,7 @@ where Ok(()) } -pub fn verify_invalid_domain_extrinsics_root_fraud_proof< - CBlock, - DomainNumber, - DomainHash, - Balance, - Hashing, - SK, - DE, ->( - consensus_state_root: CBlock::Hash, - bad_receipt: ExecutionReceipt< - NumberFor, - CBlock::Hash, - DomainNumber, - DomainHash, - Balance, - >, - fraud_proof: &InvalidExtrinsicsRootProof, -) -> Result<(), VerificationError> -where - CBlock: Block, - Hashing: Hasher, - SK: StorageKeys, - DE: DeriveExtrinsics, -{ - let InvalidExtrinsicsRootProof { - valid_bundle_digests, - randomness_storage_proof, - timestamp_storage_proof, - .. - } = fraud_proof; - - let mut bundle_extrinsics_digests = Vec::new(); - for (valid_bundle, bundle_digest) in bad_receipt - .valid_bundles - .into_iter() - .zip(valid_bundle_digests) - { - let bundle_digest_hash = BlakeTwo256::hash_of(&bundle_digest.bundle_digest); - if bundle_digest_hash != valid_bundle.bundle_digest_hash { - return Err(VerificationError::InvalidBundleDigest); - } - - bundle_extrinsics_digests.extend(bundle_digest.bundle_digest.clone()); - } - - let block_randomness = StorageProofVerifier::::verify_and_get_value::( - &consensus_state_root, - randomness_storage_proof.clone(), - SK::block_randomness_storage_key(), - ) - .map_err(|_| VerificationError::InvalidProof)?; - - let timestamp = StorageProofVerifier::::verify_and_get_value::( - &consensus_state_root, - timestamp_storage_proof.clone(), - SK::timestamp_storage_key(), - ) - .map_err(|_| VerificationError::InvalidProof)?; - - let shuffling_seed = - H256::decode(&mut extrinsics_shuffling_seed::(block_randomness).as_ref()) - .map_err(|_| VerificationError::FailedToDecode)?; - - let mut ordered_extrinsics = deduplicate_and_shuffle_extrinsics( - bundle_extrinsics_digests, - Randomness::from(shuffling_seed.to_fixed_bytes()), - ); - - let timestamp_extrinsic = - ExtrinsicDigest::new::>(DE::derive_timestamp_extrinsic(timestamp)); - ordered_extrinsics.insert(0, timestamp_extrinsic); - - let ordered_trie_node_values = ordered_extrinsics - .iter() - .map(|ext_digest| match ext_digest { - ExtrinsicDigest::Data(data) => Value::Inline(data), - ExtrinsicDigest::Hash(hash) => Value::Node(hash.0.as_slice()), - }) - .collect(); - - // TODO: domain runtime upgrade extrinsic - let extrinsics_root = - valued_ordered_trie_root::>(ordered_trie_node_values); - if bad_receipt.domain_block_extrinsic_root == extrinsics_root { - return Err(VerificationError::InvalidProof); - } - - Ok(()) -} - -fn extrinsics_shuffling_seed(block_randomness: Randomness) -> Hashing::Out +pub fn extrinsics_shuffling_seed(block_randomness: Randomness) -> Hashing::Out where Hashing: Hasher, { diff --git a/crates/subspace-runtime/src/lib.rs b/crates/subspace-runtime/src/lib.rs index 5bc085a3f24..267993a4889 100644 --- a/crates/subspace-runtime/src/lib.rs +++ b/crates/subspace-runtime/src/lib.rs @@ -41,7 +41,6 @@ use domain_runtime_primitives::{ BlockNumber as DomainNumber, Hash as DomainHash, MultiAccountId, TryConvertBack, }; use frame_support::inherent::ProvideInherent; -use frame_support::storage::generator::StorageValue; use frame_support::traits::{ConstU16, ConstU32, ConstU64, ConstU8, Currency, Everything, Get}; use frame_support::weights::constants::{RocksDbWeight, WEIGHT_REF_TIME_PER_SECOND}; use frame_support::weights::{ConstantMultiplier, IdentityFee, Weight}; @@ -59,7 +58,7 @@ use sp_consensus_subspace::{ Vote, }; use sp_core::crypto::{ByteArray, KeyTypeId}; -use sp_core::storage::{StateVersion, StorageKey}; +use sp_core::storage::StateVersion; use sp_core::{OpaqueMetadata, H256}; use sp_domains::bundle_producer_election::BundleProducerElectionParams; use sp_domains::{ @@ -619,27 +618,6 @@ parameter_types! { pub const MaxPendingStakingOperation: u32 = 100; } -pub struct StorageKeys; -impl sp_domains::fraud_proof::StorageKeys for StorageKeys { - fn block_randomness_storage_key() -> StorageKey { - StorageKey( - pallet_subspace::pallet::BlockRandomness::::storage_value_final_key().to_vec(), - ) - } - - fn timestamp_storage_key() -> StorageKey { - StorageKey(pallet_timestamp::pallet::Now::::storage_value_final_key().to_vec()) - } -} - -pub struct DeriveExtrinsics; -impl sp_domains::fraud_proof::DeriveExtrinsics for DeriveExtrinsics { - fn derive_timestamp_extrinsic(now: Moment) -> Vec { - UncheckedExtrinsic::new_unsigned(pallet_timestamp::Call::::set { now }.into()) - .encode() - } -} - impl pallet_domains::Config for Runtime { type RuntimeEvent = RuntimeEvent; type DomainNumber = DomainNumber; @@ -665,8 +643,6 @@ impl pallet_domains::Config for Runtime { type TreasuryAccount = TreasuryAccount; type MaxPendingStakingOperation = MaxPendingStakingOperation; type Randomness = Subspace; - type StorageKeys = StorageKeys; - type DeriveExtrinsics = DeriveExtrinsics; } pub struct StakingOnReward; @@ -1112,14 +1088,6 @@ impl_runtime_apis! { fn domain_state_root(domain_id: DomainId, number: DomainNumber, hash: DomainHash) -> Option{ Domains::domain_state_root(domain_id, number, hash) } - - fn block_randomness_storage_key() -> Vec { - pallet_subspace::pallet::BlockRandomness::::storage_value_final_key().to_vec() - } - - fn timestamp_storage_key() -> Vec { - pallet_timestamp::pallet::Now::::storage_value_final_key().to_vec() - } } impl sp_domains::BundleProducerElectionApi for Runtime { diff --git a/crates/subspace-service/src/lib.rs b/crates/subspace-service/src/lib.rs index 7c0f19b1b75..71b9064da26 100644 --- a/crates/subspace-service/src/lib.rs +++ b/crates/subspace-service/src/lib.rs @@ -35,6 +35,7 @@ use crate::metrics::NodeMetrics; use crate::tx_pre_validator::ConsensusChainTxPreValidator; use core::sync::atomic::{AtomicU32, Ordering}; use cross_domain_message_gossip::cdm_gossip_peers_set_config; +use domain_runtime_primitives::opaque::Block as DomainBlock; use domain_runtime_primitives::{BlockNumber as DomainNumber, Hash as DomainHash}; pub use dsn::DsnConfig; use frame_system_rpc_runtime_api::AccountNonceApi; @@ -77,7 +78,7 @@ use sp_consensus_subspace::digests::extract_pre_digest; use sp_consensus_subspace::{ FarmerPublicKey, KzgExtension, PosExtension, PotExtension, PotNextSlotInput, SubspaceApi, }; -use sp_core::traits::SpawnEssentialNamed; +use sp_core::traits::{CodeExecutor, SpawnEssentialNamed}; use sp_core::H256; use sp_domains::transaction::PreValidationObjectApi; use sp_domains::DomainsApi; @@ -228,21 +229,25 @@ pub struct SubspaceConfiguration { pub timekeeper_cpu_cores: HashSet, } -struct SubspaceExtensionsFactory { +struct SubspaceExtensionsFactory { kzg: Kzg, client: Arc, pot_verifier: PotVerifier, - _pos_table: PhantomData, + executor: Arc, + _pos_table: PhantomData<(PosTable, DomainBlock)>, } -impl ExtensionsFactory - for SubspaceExtensionsFactory +impl ExtensionsFactory + for SubspaceExtensionsFactory where PosTable: Table, Block: BlockT, Block::Hash: From, + DomainBlock: BlockT, Client: HeaderBackend + ProvideRuntimeApi + Send + Sync + 'static, - Client::Api: SubspaceApi, + Client::Api: SubspaceApi + + DomainsApi, DomainBlock::Hash>, + ExecutorDispatch: CodeExecutor, { fn extensions_for( &self, @@ -357,7 +362,10 @@ where })); exts.register(FraudProofExtension::new(Arc::new( - FraudProofHostFunctionsImpl::new(self.client.clone()), + FraudProofHostFunctionsImpl::<_, _, DomainBlock, ExecutorDispatch>::new( + self.client.clone(), + self.executor.clone(), + ), ))); exts @@ -456,14 +464,24 @@ where PotSeed::from_genesis(client.info().genesis_hash.as_ref(), pot_external_entropy), POT_VERIFIER_CACHE_SIZE, ); - client.execution_extensions().set_extensions_factory( - SubspaceExtensionsFactory:: { + + let invalid_state_transition_proof_verifier = InvalidStateTransitionProofVerifier::new( + client.clone(), + executor.clone(), + VerifierClient::new(client.clone()), + ); + + let executor = Arc::new(executor); + + client + .execution_extensions() + .set_extensions_factory(SubspaceExtensionsFactory:: { kzg: kzg.clone(), client: Arc::clone(&client), pot_verifier: pot_verifier.clone(), + executor: executor.clone(), _pos_table: PhantomData, - }, - ); + }); let telemetry = telemetry.map(|(worker, telemetry)| { task_manager @@ -476,13 +494,7 @@ where let invalid_transaction_proof_verifier = InvalidTransactionProofVerifier::new( client.clone(), - Arc::new(executor.clone()), - VerifierClient::new(client.clone()), - ); - - let invalid_state_transition_proof_verifier = InvalidStateTransitionProofVerifier::new( - client.clone(), - executor, + executor.clone(), VerifierClient::new(client.clone()), ); diff --git a/domains/client/block-preprocessor/src/inherents.rs b/domains/client/block-preprocessor/src/inherents.rs index 4c93c1b5da1..0bfe9b0815c 100644 --- a/domains/client/block-preprocessor/src/inherents.rs +++ b/domains/client/block-preprocessor/src/inherents.rs @@ -42,12 +42,9 @@ where .runtime_api() .timestamp(consensus_block_hash)?; - let mut inherent_exts = vec![]; - if let Some(inherent_timestamp) = - domain_runtime_api.construct_timestamp_inherent_extrinsic(domain_parent_hash, moment)? - { - inherent_exts.push(inherent_timestamp) - } + let inherent_exts = + vec![domain_runtime_api + .construct_timestamp_inherent_extrinsic(domain_parent_hash, moment)?]; Ok(inherent_exts) } diff --git a/domains/client/block-preprocessor/src/runtime_api.rs b/domains/client/block-preprocessor/src/runtime_api.rs index 4f54e86e081..bd5f5d477c1 100644 --- a/domains/client/block-preprocessor/src/runtime_api.rs +++ b/domains/client/block-preprocessor/src/runtime_api.rs @@ -26,7 +26,7 @@ pub trait InherentExtrinsicConstructor { &self, at: Block::Hash, moment: subspace_runtime_primitives::Moment, - ) -> Result, ApiError>; + ) -> Result; } /// Trait to wrap the new domain runtime as an extrinsic of diff --git a/domains/client/block-preprocessor/src/runtime_api_full.rs b/domains/client/block-preprocessor/src/runtime_api_full.rs index 3afd53c177a..d1f5acab99b 100644 --- a/domains/client/block-preprocessor/src/runtime_api_full.rs +++ b/domains/client/block-preprocessor/src/runtime_api_full.rs @@ -58,7 +58,7 @@ where &self, at: Block::Hash, moment: Moment, - ) -> Result, ApiError> { + ) -> Result { let api = self.client.runtime_api(); api.construct_inherent_timestamp_extrinsic(at, moment) } diff --git a/domains/client/block-preprocessor/src/runtime_api_light.rs b/domains/client/block-preprocessor/src/runtime_api_light.rs index 69ba683668c..4241531339b 100644 --- a/domains/client/block-preprocessor/src/runtime_api_light.rs +++ b/domains/client/block-preprocessor/src/runtime_api_light.rs @@ -216,7 +216,7 @@ where &self, at: Block::Hash, moment: Moment, - ) -> Result, ApiError> { + ) -> Result { >::construct_inherent_timestamp_extrinsic( self, at, moment, ) diff --git a/domains/client/domain-operator/src/fraud_proof.rs b/domains/client/domain-operator/src/fraud_proof.rs index f07ec092867..db7a0152d1b 100644 --- a/domains/client/domain-operator/src/fraud_proof.rs +++ b/domains/client/domain-operator/src/fraud_proof.rs @@ -213,28 +213,11 @@ where }); } - let consensus_runtime = self.consensus_client.runtime_api(); - let block_randomness_storage_key = - consensus_runtime.block_randomness_storage_key(consensus_block_hash)?; - let randomness_storage_proof = self.consensus_client.read_proof( - consensus_block_hash, - &mut [block_randomness_storage_key.as_slice()].into_iter(), - )?; - - let timestamp_storage_key = - consensus_runtime.timestamp_storage_key(consensus_block_hash)?; - let timestamp_storage_proof = self.consensus_client.read_proof( - consensus_block_hash, - &mut [timestamp_storage_key.as_slice()].into_iter(), - )?; - Ok(FraudProof::InvalidExtrinsicsRoot( InvalidExtrinsicsRootProof { domain_id, bad_receipt_hash, valid_bundle_digests, - randomness_storage_proof, - timestamp_storage_proof, }, )) } diff --git a/domains/primitives/runtime/src/lib.rs b/domains/primitives/runtime/src/lib.rs index b7c1755a821..fc6952186c2 100644 --- a/domains/primitives/runtime/src/lib.rs +++ b/domains/primitives/runtime/src/lib.rs @@ -203,6 +203,6 @@ sp_api::decl_runtime_apis! { /// Api that construct inherent extrinsics. pub trait InherentExtrinsicApi { /// Api to construct inherent timestamp extrinsic from given time - fn construct_inherent_timestamp_extrinsic(moment: Moment) -> Option; + fn construct_inherent_timestamp_extrinsic(moment: Moment) -> Block::Extrinsic; } } diff --git a/domains/runtime/evm/src/lib.rs b/domains/runtime/evm/src/lib.rs index 1a120e71bf3..e4581d22afd 100644 --- a/domains/runtime/evm/src/lib.rs +++ b/domains/runtime/evm/src/lib.rs @@ -884,12 +884,10 @@ impl_runtime_apis! { } impl domain_runtime_primitives::InherentExtrinsicApi for Runtime { - fn construct_inherent_timestamp_extrinsic(moment: Moment) -> Option<::Extrinsic> { - Some( - UncheckedExtrinsic::new_unsigned( - pallet_timestamp::Call::set{ now: moment }.into() - ) - ) + fn construct_inherent_timestamp_extrinsic(moment: Moment) -> ::Extrinsic { + UncheckedExtrinsic::new_unsigned( + pallet_timestamp::Call::set{ now: moment }.into() + ) } } diff --git a/domains/test/runtime/evm/src/lib.rs b/domains/test/runtime/evm/src/lib.rs index da0cde4bcf1..976b84ec290 100644 --- a/domains/test/runtime/evm/src/lib.rs +++ b/domains/test/runtime/evm/src/lib.rs @@ -881,12 +881,10 @@ impl_runtime_apis! { } impl domain_runtime_primitives::InherentExtrinsicApi for Runtime { - fn construct_inherent_timestamp_extrinsic(moment: Moment) -> Option<::Extrinsic> { - Some( - UncheckedExtrinsic::new_unsigned( - pallet_timestamp::Call::set{ now: moment }.into() - ) - ) + fn construct_inherent_timestamp_extrinsic(moment: Moment) -> ::Extrinsic { + UncheckedExtrinsic::new_unsigned( + pallet_timestamp::Call::set{ now: moment }.into() + ) } } diff --git a/test/subspace-test-runtime/src/lib.rs b/test/subspace-test-runtime/src/lib.rs index 4d729e1bc04..e3c719d9640 100644 --- a/test/subspace-test-runtime/src/lib.rs +++ b/test/subspace-test-runtime/src/lib.rs @@ -29,7 +29,6 @@ use domain_runtime_primitives::{ BlockNumber as DomainNumber, Hash as DomainHash, MultiAccountId, TryConvertBack, }; use frame_support::inherent::ProvideInherent; -use frame_support::storage::generator::StorageValue; use frame_support::traits::{ ConstU128, ConstU16, ConstU32, ConstU64, ConstU8, Currency, ExistenceRequirement, Get, Imbalance, WithdrawReasons, @@ -52,7 +51,7 @@ use sp_consensus_subspace::{ Vote, }; use sp_core::crypto::{ByteArray, KeyTypeId}; -use sp_core::storage::{StateVersion, StorageKey}; +use sp_core::storage::StateVersion; use sp_core::{Hasher, OpaqueMetadata, H256}; use sp_domains::bundle_producer_election::BundleProducerElectionParams; use sp_domains::fraud_proof::FraudProof; @@ -643,27 +642,6 @@ parameter_types! { pub const MaxPendingStakingOperation: u32 = 100; } -pub struct StorageKeys; -impl sp_domains::fraud_proof::StorageKeys for StorageKeys { - fn block_randomness_storage_key() -> StorageKey { - StorageKey( - pallet_subspace::pallet::BlockRandomness::::storage_value_final_key().to_vec(), - ) - } - - fn timestamp_storage_key() -> StorageKey { - StorageKey(pallet_timestamp::pallet::Now::::storage_value_final_key().to_vec()) - } -} - -pub struct DeriveExtrinsics; -impl sp_domains::fraud_proof::DeriveExtrinsics for DeriveExtrinsics { - fn derive_timestamp_extrinsic(now: Moment) -> Vec { - UncheckedExtrinsic::new_unsigned(pallet_timestamp::Call::::set { now }.into()) - .encode() - } -} - impl pallet_domains::Config for Runtime { type RuntimeEvent = RuntimeEvent; type DomainNumber = DomainNumber; @@ -689,8 +667,6 @@ impl pallet_domains::Config for Runtime { type TreasuryAccount = TreasuryAccount; type MaxPendingStakingOperation = MaxPendingStakingOperation; type Randomness = Subspace; - type StorageKeys = StorageKeys; - type DeriveExtrinsics = DeriveExtrinsics; } parameter_types! { @@ -1401,14 +1377,6 @@ impl_runtime_apis! { fn domain_state_root(domain_id: DomainId, number: DomainNumber, hash: DomainHash) -> Option{ Domains::domain_state_root(domain_id, number, hash) } - - fn block_randomness_storage_key() -> Vec { - pallet_subspace::pallet::BlockRandomness::::storage_value_final_key().to_vec() - } - - fn timestamp_storage_key() -> Vec { - pallet_timestamp::pallet::Now::::storage_value_final_key().to_vec() - } } impl sp_domains::BundleProducerElectionApi for Runtime { diff --git a/test/subspace-test-service/src/lib.rs b/test/subspace-test-service/src/lib.rs index 0848d5e3e22..09e6c742fee 100644 --- a/test/subspace-test-service/src/lib.rs +++ b/test/subspace-test-service/src/lib.rs @@ -20,6 +20,7 @@ use codec::{Decode, Encode}; use cross_domain_message_gossip::GossipWorkerBuilder; +use domain_runtime_primitives::opaque::Block as DomainBlock; use domain_runtime_primitives::BlockNumber as DomainNumber; use futures::channel::mpsc; use futures::{select, FutureExt, StreamExt}; @@ -56,9 +57,9 @@ use sp_consensus::{BlockOrigin, Error as ConsensusError}; use sp_consensus_slots::Slot; use sp_consensus_subspace::digests::{CompatibleDigestItem, PreDigest, PreDigestPotInfo}; use sp_consensus_subspace::FarmerPublicKey; -use sp_core::traits::SpawnEssentialNamed; +use sp_core::traits::{CodeExecutor, SpawnEssentialNamed}; use sp_core::H256; -use sp_domains::OpaqueBundle; +use sp_domains::{DomainsApi, OpaqueBundle}; use sp_domains_fraud_proof::{FraudProofExtension, FraudProofHostFunctionsImpl}; use sp_externalities::Extensions; use sp_inherents::{InherentData, InherentDataProvider}; @@ -175,15 +176,31 @@ type StorageChanges = sp_api::StorageChanges; type TxPreValidator = ConsensusChainTxPreValidator; -struct MockExtensionsFactory { +struct MockExtensionsFactory { consensus_client: Arc, + executor: Arc, + _phantom: PhantomData, } -impl ExtensionsFactory for MockExtensionsFactory +impl MockExtensionsFactory { + fn new(consensus_client: Arc, executor: Arc) -> Self { + Self { + consensus_client, + executor, + _phantom: Default::default(), + } + } +} + +impl ExtensionsFactory + for MockExtensionsFactory where Block: BlockT, Block::Hash: From, - Client: HeaderBackend + 'static, + DomainBlock: BlockT, + Client: HeaderBackend + ProvideRuntimeApi + 'static, + Client::Api: DomainsApi, DomainBlock::Hash>, + Executor: CodeExecutor, { fn extensions_for( &self, @@ -192,7 +209,10 @@ where ) -> Extensions { let mut exts = Extensions::new(); exts.register(FraudProofExtension::new(Arc::new( - FraudProofHostFunctionsImpl::new(self.consensus_client.clone()), + FraudProofHostFunctionsImpl::<_, _, DomainBlock, Executor>::new( + self.consensus_client.clone(), + self.executor.clone(), + ), ))); exts } @@ -269,9 +289,10 @@ impl MockConsensusNode { let client = Arc::new(client); client .execution_extensions() - .set_extensions_factory(MockExtensionsFactory { - consensus_client: client.clone(), - }); + .set_extensions_factory(MockExtensionsFactory::<_, DomainBlock, _>::new( + client.clone(), + Arc::new(executor.clone()), + )); let select_chain = sc_consensus::LongestChain::new(backend.clone());