From 48a3815da7348bc0f7815997513df23ecdaf171d Mon Sep 17 00:00:00 2001 From: Liu-Cheng Xu Date: Sun, 2 Jul 2023 17:10:22 +0800 Subject: [PATCH 1/4] Remove SettlementApi The functionalities of `SettlementApi` are merged into ExecutorApi in sp-domains, therfore, it's replaced with `ExecutorApi` if `ExecutorApi` is not there. --- crates/pallet-domains/src/lib.rs | 4 +- crates/sc-consensus-fraud-proof/src/lib.rs | 35 ++--- .../src/domain_extrinsics_builder.rs | 7 +- .../subspace-fraud-proof/src/verifier_api.rs | 122 +++--------------- crates/subspace-runtime/src/lib.rs | 52 -------- crates/subspace-service/src/lib.rs | 3 - domains/client/block-preprocessor/src/lib.rs | 3 +- .../block-preprocessor/src/xdm_verifier.rs | 106 +++------------ .../domain-executor/src/bundle_processor.rs | 17 +-- .../src/domain_bundle_producer.rs | 8 +- .../src/domain_bundle_proposer.rs | 4 +- .../src/domain_worker_starter.rs | 3 +- .../client/domain-executor/src/executor.rs | 3 +- .../domain-executor/src/parent_chain.rs | 80 +++++++----- domains/client/domain-executor/src/tests.rs | 94 +++++++------- domains/client/relayer/src/worker.rs | 76 ----------- domains/service/src/domain.rs | 19 +-- .../service/src/domain_tx_pre_validator.rs | 5 +- test/subspace-test-runtime/src/lib.rs | 52 -------- 19 files changed, 186 insertions(+), 507 deletions(-) diff --git a/crates/pallet-domains/src/lib.rs b/crates/pallet-domains/src/lib.rs index 323ce445e4..91b43b1331 100644 --- a/crates/pallet-domains/src/lib.rs +++ b/crates/pallet-domains/src/lib.rs @@ -276,8 +276,8 @@ mod pallet { let domain_id = opaque_bundle.domain_id(); // TODO: Implement the receipts processing v2. - pallet_settlement::Pallet::::track_receipt(domain_id, &opaque_bundle.receipt) - .map_err(Error::::from)?; + // pallet_settlement::Pallet::::track_receipt(domain_id, &opaque_bundle.receipt) + // .map_err(Error::::from)?; let bundle_hash = opaque_bundle.hash(); diff --git a/crates/sc-consensus-fraud-proof/src/lib.rs b/crates/sc-consensus-fraud-proof/src/lib.rs index 114006a9ab..13e31a4bb0 100644 --- a/crates/sc-consensus-fraud-proof/src/lib.rs +++ b/crates/sc-consensus-fraud-proof/src/lib.rs @@ -20,8 +20,8 @@ use codec::{Decode, Encode}; use sc_consensus::block_import::{BlockCheckParams, BlockImport, BlockImportParams, ImportResult}; use sp_api::{ProvideRuntimeApi, TransactionFor}; use sp_consensus::Error as ConsensusError; +use sp_domains::ExecutorApi; use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; -use sp_settlement::SettlementApi; use std::marker::PhantomData; use std::sync::Arc; use subspace_fraud_proof::VerifyFraudProof; @@ -62,7 +62,7 @@ impl BlockImport where Block: BlockT, Client: ProvideRuntimeApi + Send + Sync + 'static, - Client::Api: SettlementApi, + Client::Api: ExecutorApi, Inner: BlockImport, Error = ConsensusError> + Send, Verifier: VerifyFraudProof + Send, @@ -82,27 +82,28 @@ where &mut self, block: BlockImportParams, ) -> Result { - let parent_hash = *block.header.parent_hash(); + let _parent_hash = *block.header.parent_hash(); if !block.state_action.skip_execution_checks() { - if let Some(extrinsics) = &block.body { + if let Some(_extrinsics) = &block.body { // TODO: Fetch the registered domains properly // We may change `extract_fraud_proofs` API to return the fraud proofs for all // domains instead of specifying the domain_id each time for the efficiency. - let registered_domains = vec![]; - for domain_id in registered_domains { - let fraud_proofs = self - .client - .runtime_api() - .extract_fraud_proofs(parent_hash, extrinsics.clone(), domain_id) - .map_err(|e| ConsensusError::ClientImport(e.to_string()))?; + // let registered_domains = vec![]; + // for domain_id in registered_domains { + // TODO: Implement `extract_fraud_proofs` when proceeding to fraud proof v2. + // let fraud_proofs = self + // .client + // .runtime_api() + // .extract_fraud_proofs(parent_hash, extrinsics.clone(), domain_id) + // .map_err(|e| ConsensusError::ClientImport(e.to_string()))?; - for fraud_proof in fraud_proofs { - self.fraud_proof_verifier - .verify_fraud_proof(&fraud_proof) - .map_err(|e| ConsensusError::Other(Box::new(e)))?; - } - } + // for fraud_proof in fraud_proofs { + // self.fraud_proof_verifier + // .verify_fraud_proof(&fraud_proof) + // .map_err(|e| ConsensusError::Other(Box::new(e)))?; + // } + // } } } diff --git a/crates/subspace-fraud-proof/src/domain_extrinsics_builder.rs b/crates/subspace-fraud-proof/src/domain_extrinsics_builder.rs index e70cbb1e96..332976e53e 100644 --- a/crates/subspace-fraud-proof/src/domain_extrinsics_builder.rs +++ b/crates/subspace-fraud-proof/src/domain_extrinsics_builder.rs @@ -10,7 +10,6 @@ use sp_core::traits::CodeExecutor; use sp_core::H256; use sp_domains::{DomainId, ExecutorApi}; use sp_runtime::traits::Block as BlockT; -use sp_settlement::SettlementApi; use std::marker::PhantomData; use std::sync::Arc; @@ -52,8 +51,7 @@ where + Send + Sync + 'static, - PClient::Api: ExecutorApi - + SettlementApi, + PClient::Api: ExecutorApi, Executor: CodeExecutor, { /// Constructs a new instance of [`DomainExtrinsicsBuilder`]. @@ -77,8 +75,7 @@ where + Send + Sync + 'static, - PClient::Api: ExecutorApi - + SettlementApi, + PClient::Api: ExecutorApi, Executor: CodeExecutor, { fn build_domain_extrinsics( diff --git a/crates/subspace-fraud-proof/src/verifier_api.rs b/crates/subspace-fraud-proof/src/verifier_api.rs index 2749f8ee8f..1058e85dc4 100644 --- a/crates/subspace-fraud-proof/src/verifier_api.rs +++ b/crates/subspace-fraud-proof/src/verifier_api.rs @@ -2,15 +2,17 @@ //! as well as the implementation to provide convenient interfaces used in the fraud //! proof verification. +// TODO: Remove once fraud proof v2 is implemented. +#![allow(unused)] + use codec::{Decode, Encode}; use domain_runtime_primitives::Hash; use sc_client_api::HeaderBackend; use sp_api::ProvideRuntimeApi; use sp_core::H256; use sp_domains::fraud_proof::{ExecutionPhase, InvalidStateTransitionProof, VerificationError}; -use sp_domains::DomainId; +use sp_domains::{DomainId, ExecutorApi}; use sp_runtime::traits::{Block as BlockT, NumberFor}; -use sp_settlement::SettlementApi; use std::marker::PhantomData; use std::sync::Arc; @@ -45,8 +47,6 @@ pub trait VerifierApi { } /// A wrapper of primary chain client/system domain client in common. -/// -/// Both primary chain client and system domain client maintains the state of receipts, i.e., implements `SettlementApi`. pub struct VerifierClient { client: Arc, _phantom: PhantomData, @@ -75,7 +75,7 @@ impl VerifierApi for VerifierClient where Block: BlockT, Client: ProvideRuntimeApi + HeaderBackend, - Client::Api: SettlementApi, + Client::Api: ExecutorApi, { // TODO: It's not necessary to require `pre_state_root` in the proof and then verify, it can // be just retrieved by the verifier itself according the execution phase, which requires some @@ -85,118 +85,36 @@ where // Related: https://github.com/subspace/subspace/pull/1240#issuecomment-1476212007 fn verify_pre_state_root( &self, - invalid_state_transition_proof: &InvalidStateTransitionProof, + _invalid_state_transition_proof: &InvalidStateTransitionProof, ) -> Result<(), VerificationError> { - let InvalidStateTransitionProof { - domain_id, - parent_number, - bad_receipt_hash, - pre_state_root, - execution_phase, - .. - } = invalid_state_transition_proof; - - let pre_state_root_onchain = match execution_phase { - ExecutionPhase::InitializeBlock { domain_parent_hash } => { - self.client.runtime_api().state_root( - self.client.info().best_hash, - *domain_id, - NumberFor::::from(*parent_number), - Block::Hash::decode(&mut domain_parent_hash.encode().as_slice())?, - )? - } - ExecutionPhase::ApplyExtrinsic(trace_index_of_pre_state_root) - | ExecutionPhase::FinalizeBlock { - total_extrinsics: trace_index_of_pre_state_root, - } => { - let trace = self.client.runtime_api().execution_trace( - self.client.info().best_hash, - *domain_id, - *bad_receipt_hash, - )?; - - trace.get(*trace_index_of_pre_state_root as usize).copied() - } - }; - - match pre_state_root_onchain { - Some(expected_pre_state_root) if expected_pre_state_root == *pre_state_root => Ok(()), - res => { - tracing::debug!( - "Invalid `pre_state_root` in InvalidStateTransitionProof for {domain_id:?}, expected: {res:?}, got: {pre_state_root:?}", - ); - Err(VerificationError::InvalidPreStateRoot) - } - } + // TODO: Implement or remove entirely. + Ok(()) } fn verify_post_state_root( &self, - invalid_state_transition_proof: &InvalidStateTransitionProof, + _invalid_state_transition_proof: &InvalidStateTransitionProof, ) -> Result<(), VerificationError> { - let InvalidStateTransitionProof { - domain_id, - bad_receipt_hash, - execution_phase, - post_state_root, - .. - } = invalid_state_transition_proof; - - let trace = self.client.runtime_api().execution_trace( - self.client.info().best_hash, - *domain_id, - *bad_receipt_hash, - )?; - - let post_state_root_onchain = match execution_phase { - ExecutionPhase::InitializeBlock { .. } => trace - .get(0) - .ok_or(VerificationError::PostStateRootNotFound)?, - ExecutionPhase::ApplyExtrinsic(trace_index_of_post_state_root) - | ExecutionPhase::FinalizeBlock { - total_extrinsics: trace_index_of_post_state_root, - } => trace - .get(*trace_index_of_post_state_root as usize + 1) - .ok_or(VerificationError::PostStateRootNotFound)?, - }; - - if post_state_root_onchain == post_state_root { - Err(VerificationError::SamePostStateRoot) - } else { - Ok(()) - } + // TODO: Implement or remove entirely. + Ok(()) } fn primary_hash( &self, - domain_id: DomainId, - domain_block_number: u32, + _domain_id: DomainId, + _domain_block_number: u32, ) -> Result { - self.client - .runtime_api() - .primary_hash( - self.client.info().best_hash, - domain_id, - domain_block_number.into(), - )? - .and_then(|primary_hash| Decode::decode(&mut primary_hash.encode().as_slice()).ok()) - .ok_or(VerificationError::PrimaryHashNotFound) + // TODO: Remove entirely. + Err(VerificationError::PrimaryHashNotFound) } fn state_root( &self, - domain_id: DomainId, - domain_block_number: u32, - domain_block_hash: H256, + _domain_id: DomainId, + _domain_block_number: u32, + _domain_block_hash: H256, ) -> Result { - self.client - .runtime_api() - .state_root( - self.client.info().best_hash, - domain_id, - NumberFor::::from(domain_block_number), - Block::Hash::decode(&mut domain_block_hash.encode().as_slice())?, - )? - .ok_or(VerificationError::DomainStateRootNotFound) + // TODO: Implement or remove entirely. + Err(VerificationError::DomainStateRootNotFound) } } diff --git a/crates/subspace-runtime/src/lib.rs b/crates/subspace-runtime/src/lib.rs index d2f1f3195f..cbd0bc847b 100644 --- a/crates/subspace-runtime/src/lib.rs +++ b/crates/subspace-runtime/src/lib.rs @@ -765,58 +765,6 @@ impl_runtime_apis! { } } - impl sp_settlement::SettlementApi for Runtime { - fn execution_trace(domain_id: DomainId, receipt_hash: H256) -> Vec { - Settlement::receipts(domain_id, receipt_hash).map(|receipt| receipt.trace).unwrap_or_default() - } - - fn state_root( - domain_id: DomainId, - domain_block_number: NumberFor, - domain_block_hash: Hash, - ) -> Option { - Settlement::state_root((domain_id, domain_block_number, domain_block_hash)) - } - - fn primary_hash(domain_id: DomainId, domain_block_number: BlockNumber) -> Option { - Settlement::primary_hash(domain_id, domain_block_number) - } - - fn receipts_pruning_depth() -> BlockNumber { - ReceiptsPruningDepth::get() - } - - fn head_receipt_number(domain_id: DomainId) -> NumberFor { - Settlement::head_receipt_number(domain_id) - } - - fn oldest_receipt_number(domain_id: DomainId) -> NumberFor { - Settlement::oldest_receipt_number(domain_id) - } - - fn maximum_receipt_drift() -> NumberFor { - MaximumReceiptDrift::get() - } - - fn extract_receipts( - extrinsics: Vec<::Extrinsic>, - domain_id: DomainId, - ) -> Vec, ::Hash, domain_runtime_primitives::Hash>> { - crate::domains::extract_receipts(extrinsics, domain_id) - } - - fn extract_fraud_proofs( - extrinsics: Vec<::Extrinsic>, - domain_id: DomainId, - ) -> Vec, ::Hash>> { - crate::domains::extract_fraud_proofs(extrinsics, domain_id) - } - - fn submit_fraud_proof_unsigned(fraud_proof: FraudProof, ::Hash>) { - Domains::submit_fraud_proof_unsigned(fraud_proof) - } - } - impl sp_domains::transaction::PreValidationObjectApi for Runtime { fn extract_pre_validation_object( extrinsic: ::Extrinsic, diff --git a/crates/subspace-service/src/lib.rs b/crates/subspace-service/src/lib.rs index 64d64006a9..2b02c43052 100644 --- a/crates/subspace-service/src/lib.rs +++ b/crates/subspace-service/src/lib.rs @@ -77,7 +77,6 @@ use sp_objects::ObjectsApi; use sp_offchain::OffchainWorkerApi; use sp_runtime::traits::{Block as BlockT, BlockIdTo, NumberFor}; use sp_session::SessionKeys; -use sp_settlement::SettlementApi; use sp_transaction_pool::runtime_api::TaggedTransactionQueue; use std::marker::PhantomData; use std::sync::{Arc, Mutex}; @@ -291,7 +290,6 @@ where + TaggedTransactionQueue + ExecutorApi + ObjectsApi - + SettlementApi + PreValidationObjectApi + SubspaceApi, ExecutorDispatch: NativeExecutionDispatch + 'static, @@ -554,7 +552,6 @@ where + TransactionPaymentApi + ExecutorApi + ObjectsApi - + SettlementApi + PreValidationObjectApi + SubspaceApi, ExecutorDispatch: NativeExecutionDispatch + 'static, diff --git a/domains/client/block-preprocessor/src/lib.rs b/domains/client/block-preprocessor/src/lib.rs index 2406efd339..0754a43447 100644 --- a/domains/client/block-preprocessor/src/lib.rs +++ b/domains/client/block-preprocessor/src/lib.rs @@ -35,7 +35,6 @@ use sp_blockchain::HeaderBackend; use sp_domains::{DomainId, ExecutorApi, OpaqueBundles}; use sp_runtime::generic::DigestItem; use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor}; -use sp_settlement::SettlementApi; use std::borrow::Cow; use std::collections::{BTreeMap, VecDeque}; use std::fmt::Debug; @@ -253,7 +252,7 @@ where + Send + Sync + 'static, - PClient::Api: ExecutorApi + SettlementApi, + PClient::Api: ExecutorApi, { pub fn new( domain_id: DomainId, diff --git a/domains/client/block-preprocessor/src/xdm_verifier.rs b/domains/client/block-preprocessor/src/xdm_verifier.rs index 71880cda62..9e4c3712a7 100644 --- a/domains/client/block-preprocessor/src/xdm_verifier.rs +++ b/domains/client/block-preprocessor/src/xdm_verifier.rs @@ -1,87 +1,20 @@ +// TODO: Remove one the subsequent TODO is resolved. +#![allow(unused)] + use crate::runtime_api::StateRootExtractor; use sp_api::ProvideRuntimeApi; use sp_blockchain::{Error, HeaderBackend}; -use sp_domains::DomainId; +use sp_domains::{DomainId, ExecutorApi}; use sp_messenger::MessengerApi; use sp_runtime::traits::{Block as BlockT, CheckedSub, Header, NumberFor}; -use sp_settlement::SettlementApi; use std::sync::Arc; -/// Verifies if the xdm has the correct proof generated from known parent block. -/// This is used by Core domain nodes. -/// Core domains nodes use this to verify an XDM coming from other domains. -/// Returns either true if the XDM is valid else false. -/// Returns Error when required calls to fetch header info fails. -pub fn verify_xdm_with_system_domain_client( - system_domain_client: &Arc, - at: Block::Hash, - extrinsic: &Block::Extrinsic, - state_root_extractor: &SRE, -) -> Result -where - SClient: HeaderBackend + ProvideRuntimeApi + 'static, - SClient::Api: MessengerApi> + SettlementApi, - Block: BlockT, - SBlock: BlockT, - SBlock::Hash: From, - NumberFor: From>, - PBlock: BlockT, - SRE: StateRootExtractor, -{ - if let Ok(state_roots) = state_root_extractor.extract_state_roots(at, extrinsic) { - // verify system domain state root - let header = system_domain_client - .header(state_roots.system_domain_block_info.block_hash.into())? - .ok_or(Error::MissingHeader(format!( - "hash: {}", - state_roots.system_domain_block_info.block_hash - )))?; - - if *header.number() != state_roots.system_domain_block_info.block_number.into() { - return Ok(false); - } - - if *header.state_root() != state_roots.system_domain_state_root.into() { - return Ok(false); - } - - // verify core domain state root and the if the number is K-deep. - let best_hash = system_domain_client.info().best_hash; - let api = system_domain_client.runtime_api(); - if let Some((domain_id, core_domain_info, core_domain_state_root)) = - state_roots.core_domain_info - { - let best_number = api.head_receipt_number(best_hash, domain_id)?; - if let Some(confirmed_number) = - best_number.checked_sub(&api.confirmation_depth(best_hash)?) - { - if confirmed_number < core_domain_info.block_number.into() { - return Ok(false); - } - } - - if let Some(expected_core_domain_state_root) = api.state_root( - best_hash, - domain_id, - core_domain_info.block_number.into(), - core_domain_info.block_hash.into(), - )? { - if expected_core_domain_state_root != core_domain_state_root { - return Ok(false); - } - } - } - } - - Ok(true) -} - /// Verifies if the xdm has the correct proof generated from known parent block. /// This is used by the System domain to validate Extrinsics. /// Returns either true if the XDM is valid else false. /// Returns Error when required calls to fetch header info fails. pub fn verify_xdm_with_primary_chain_client( - domain_id: DomainId, + _domain_id: DomainId, primary_chain_client: &Arc, at: SBlock::Hash, state_root_extractor: &SRE, @@ -89,27 +22,28 @@ pub fn verify_xdm_with_primary_chain_client( ) -> Result where PClient: HeaderBackend + ProvideRuntimeApi + 'static, - PClient::Api: SettlementApi, + PClient::Api: ExecutorApi, SBlock: BlockT, PBlock: BlockT, NumberFor: From>, PBlock::Hash: From, SRE: StateRootExtractor, { - if let Ok(state_roots) = state_root_extractor.extract_state_roots(at, extrinsic) { + if let Ok(_state_roots) = state_root_extractor.extract_state_roots(at, extrinsic) { // verify system domain state root - let best_hash = primary_chain_client.info().best_hash; - let primary_runtime = primary_chain_client.runtime_api(); - if let Some(system_domain_state_root) = primary_runtime.state_root( - best_hash, - domain_id, - state_roots.system_domain_block_info.block_number.into(), - state_roots.system_domain_block_info.block_hash.into(), - )? { - if system_domain_state_root != state_roots.system_domain_state_root { - return Ok(false); - } - } + let _best_hash = primary_chain_client.info().best_hash; + let _primary_runtime = primary_chain_client.runtime_api(); + // TODO: Add `state_root` in ExecutorApi + // if let Some(system_domain_state_root) = primary_runtime.state_root( + // best_hash, + // domain_id, + // state_roots.system_domain_block_info.block_number.into(), + // state_roots.system_domain_block_info.block_hash.into(), + // )? { + // if system_domain_state_root != state_roots.system_domain_state_root { + // return Ok(false); + // } + // } } Ok(true) diff --git a/domains/client/domain-executor/src/bundle_processor.rs b/domains/client/domain-executor/src/bundle_processor.rs index b57a1314db..e789f9cc7e 100644 --- a/domains/client/domain-executor/src/bundle_processor.rs +++ b/domains/client/domain-executor/src/bundle_processor.rs @@ -11,9 +11,8 @@ use sp_core::traits::CodeExecutor; use sp_domains::{DomainId, ExecutorApi}; use sp_keystore::KeystorePtr; use sp_messenger::MessengerApi; -use sp_runtime::traits::{Block as BlockT, HashFor}; +use sp_runtime::traits::{Block as BlockT, HashFor, One}; use sp_runtime::Digest; -use sp_settlement::SettlementApi; use std::sync::Arc; type DomainReceiptsChecker = ReceiptsChecker< @@ -91,7 +90,7 @@ where + BlockBackend + ProvideRuntimeApi + 'static, - PClient::Api: ExecutorApi + SettlementApi + 'static, + PClient::Api: ExecutorApi + 'static, Backend: sc_client_api::Backend + 'static, TransactionFor: sp_trie::HashDBT, sp_trie::DBValue>, E: CodeExecutor, @@ -185,11 +184,13 @@ where ) .await?; - let head_receipt_number = self - .primary_chain_client - .runtime_api() - .head_receipt_number(primary_hash, self.domain_id)? - .into(); + // TODO: Retrieve using consensus chain runtime API + let head_receipt_number = domain_block_result.header_number - One::one(); + // let head_receipt_number = self + // .primary_chain_client + // .runtime_api() + // .head_receipt_number(primary_hash, self.domain_id)? + // .into(); assert!( domain_block_result.header_number > head_receipt_number, diff --git a/domains/client/domain-executor/src/domain_bundle_producer.rs b/domains/client/domain-executor/src/domain_bundle_producer.rs index b03a058e52..25e985344e 100644 --- a/domains/client/domain-executor/src/domain_bundle_producer.rs +++ b/domains/client/domain-executor/src/domain_bundle_producer.rs @@ -160,9 +160,11 @@ where let should_skip_slot = { let primary_block_number = primary_info.1; - let head_receipt_number = self - .parent_chain - .head_receipt_number(self.parent_chain.best_hash())?; + // TODO: Retrieve using consensus chain runtime API + let head_receipt_number = domain_best_number.saturating_sub(One::one()); + // let head_receipt_number = self + // .parent_chain + // .head_receipt_number(self.parent_chain.best_hash())?; // Receipt for block #0 does not exist, simply skip slot here to bypasss this case and // make the code cleaner diff --git a/domains/client/domain-executor/src/domain_bundle_proposer.rs b/domains/client/domain-executor/src/domain_bundle_proposer.rs index 0d106ccc90..cf321b5f4a 100644 --- a/domains/client/domain-executor/src/domain_bundle_proposer.rs +++ b/domains/client/domain-executor/src/domain_bundle_proposer.rs @@ -156,7 +156,9 @@ where ParentChain: ParentChainInterface, { let parent_chain_block_hash = parent_chain.best_hash(); - let head_receipt_number = parent_chain.head_receipt_number(parent_chain_block_hash)?; + // TODO: Retrieve using consensus chain runtime API + let head_receipt_number = header_number.saturating_sub(One::one()); + // let head_receipt_number = parent_chain.head_receipt_number(parent_chain_block_hash)?; let max_drift = parent_chain.maximum_receipt_drift(parent_chain_block_hash)?; tracing::trace!( diff --git a/domains/client/domain-executor/src/domain_worker_starter.rs b/domains/client/domain-executor/src/domain_worker_starter.rs index 9c631526c3..c6ab3aa2c6 100644 --- a/domains/client/domain-executor/src/domain_worker_starter.rs +++ b/domains/client/domain-executor/src/domain_worker_starter.rs @@ -36,7 +36,6 @@ use sp_core::traits::{CodeExecutor, SpawnEssentialNamed}; use sp_domains::ExecutorApi; use sp_messenger::MessengerApi; use sp_runtime::traits::{HashFor, NumberFor}; -use sp_settlement::SettlementApi; use std::sync::Arc; use subspace_core_primitives::Blake2b256Hash; use tracing::Instrument; @@ -100,7 +99,7 @@ pub(super) async fn start_worker< + ProvideRuntimeApi + BlockchainEvents + 'static, - PClient::Api: ExecutorApi + SettlementApi, + PClient::Api: ExecutorApi, TransactionPool: sc_transaction_pool_api::TransactionPool + 'static, Backend: sc_client_api::Backend + 'static, IBNS: Stream, mpsc::Sender<()>)> + Send + 'static, diff --git a/domains/client/domain-executor/src/executor.rs b/domains/client/domain-executor/src/executor.rs index 773c346418..f39e836fcd 100644 --- a/domains/client/domain-executor/src/executor.rs +++ b/domains/client/domain-executor/src/executor.rs @@ -21,7 +21,6 @@ use sp_core::traits::{CodeExecutor, SpawnEssentialNamed}; use sp_domains::ExecutorApi; use sp_messenger::MessengerApi; use sp_runtime::traits::{Block as BlockT, HashFor, NumberFor}; -use sp_settlement::SettlementApi; use std::sync::Arc; use subspace_core_primitives::Blake2b256Hash; @@ -92,7 +91,7 @@ where + Send + Sync + 'static, - PClient::Api: ExecutorApi + SettlementApi, + PClient::Api: ExecutorApi, Backend: sc_client_api::Backend + Send + Sync + 'static, TransactionFor: sp_trie::HashDBT, sp_trie::DBValue>, TransactionPool: sc_transaction_pool_api::TransactionPool + 'static, diff --git a/domains/client/domain-executor/src/parent_chain.rs b/domains/client/domain-executor/src/parent_chain.rs index 6bbef1af84..d82afd7b50 100644 --- a/domains/client/domain-executor/src/parent_chain.rs +++ b/domains/client/domain-executor/src/parent_chain.rs @@ -3,9 +3,8 @@ use sc_client_api::BlockBackend; use sp_api::{NumberFor, ProvideRuntimeApi}; use sp_blockchain::HeaderBackend; use sp_domains::fraud_proof::FraudProof; -use sp_domains::DomainId; +use sp_domains::{DomainId, ExecutorApi}; use sp_runtime::traits::Block as BlockT; -use sp_settlement::SettlementApi; use std::marker::PhantomData; use std::sync::Arc; @@ -89,7 +88,7 @@ where PBlock: BlockT, NumberFor: Into>, PClient: HeaderBackend + BlockBackend + ProvideRuntimeApi, - PClient::Api: SettlementApi, + PClient::Api: ExecutorApi, { fn best_hash(&self) -> PBlock::Hash { self.primary_chain_client.info().best_hash @@ -105,60 +104,71 @@ where &self, at: PBlock::Hash, ) -> Result, sp_api::ApiError> { - let oldest_receipt_number = self - .primary_chain_client - .runtime_api() - .oldest_receipt_number(at, self.domain_id)?; - Ok(oldest_receipt_number.into()) + // TODO: Implement when block tree is ready. + Ok(0u32.into()) + // let oldest_receipt_number = self + // .primary_chain_client + // .runtime_api() + // .oldest_receipt_number(at, self.domain_id)?; + // Ok(oldest_receipt_number.into()) } - fn head_receipt_number(&self, at: PBlock::Hash) -> Result, sp_api::ApiError> { - let head_receipt_number = self - .primary_chain_client - .runtime_api() - .head_receipt_number(at, self.domain_id)?; - Ok(head_receipt_number.into()) + fn head_receipt_number(&self, _at: PBlock::Hash) -> Result, sp_api::ApiError> { + // TODO: Implement when block tree is ready. + unimplemented!("Retrieve from consensus chain runtime") + // let head_receipt_number = self + // .primary_chain_client + // .runtime_api() + // .head_receipt_number(at, self.domain_id)?; + // Ok(head_receipt_number.into()) } fn maximum_receipt_drift( &self, - at: PBlock::Hash, + _at: PBlock::Hash, ) -> Result, sp_api::ApiError> { - let max_drift = self - .primary_chain_client - .runtime_api() - .maximum_receipt_drift(at)?; - Ok(max_drift.into()) + // TODO: Implement when block tree is ready. + Ok(256u32.into()) + // let max_drift = self + // .primary_chain_client + // .runtime_api() + // .maximum_receipt_drift(at)?; + // Ok(max_drift.into()) } fn extract_receipts( &self, - at: PBlock::Hash, - extrinsics: Vec, + _at: PBlock::Hash, + _extrinsics: Vec, ) -> Result>, sp_api::ApiError> { - self.primary_chain_client - .runtime_api() - .extract_receipts(at, extrinsics, self.domain_id) + // TODO: Implement when proceeding to fraud proof v2. + Ok(Vec::new()) + // self.primary_chain_client + // .runtime_api() + // .extract_receipts(at, extrinsics, self.domain_id) } fn extract_fraud_proofs( &self, - at: PBlock::Hash, - extrinsics: Vec, + _at: PBlock::Hash, + _extrinsics: Vec, ) -> Result>, sp_api::ApiError> { - self.primary_chain_client - .runtime_api() - .extract_fraud_proofs(at, extrinsics, self.domain_id) + // TODO: Implement when proceeding to fraud proof v2. + Ok(Vec::new()) + // self.primary_chain_client + // .runtime_api() + // .extract_fraud_proofs(at, extrinsics, self.domain_id) } fn submit_fraud_proof_unsigned( &self, - fraud_proof: FraudProof, PBlock::Hash>, + _fraud_proof: FraudProof, PBlock::Hash>, ) -> Result<(), sp_api::ApiError> { - let at = self.primary_chain_client.info().best_hash; - self.primary_chain_client - .runtime_api() - .submit_fraud_proof_unsigned(at, fraud_proof)?; + // TODO: Implement when proceeding to fraud proof v2. + // let at = self.primary_chain_client.info().best_hash; + // self.primary_chain_client + // .runtime_api() + // .submit_fraud_proof_unsigned(at, fraud_proof)?; Ok(()) } } diff --git a/domains/client/domain-executor/src/tests.rs b/domains/client/domain-executor/src/tests.rs index 585fa80b6b..4c6dc0da0f 100644 --- a/domains/client/domain-executor/src/tests.rs +++ b/domains/client/domain-executor/src/tests.rs @@ -20,7 +20,6 @@ use sp_domains::{Bundle, DomainId, ExecutorApi}; use sp_runtime::generic::{BlockId, Digest, DigestItem}; use sp_runtime::traits::{BlakeTwo256, Header as HeaderT}; use sp_runtime::OpaqueExtrinsic; -use sp_settlement::SettlementApi; use subspace_core_primitives::BlockNumber; use subspace_fraud_proof::invalid_state_transition_proof::ExecutionProver; use subspace_test_service::{ @@ -799,52 +798,53 @@ async fn pallet_domains_unsigned_extrinsics_should_work() { // able to be written to the database. produce_blocks!(ferdie, bob, 5).await.unwrap(); - let ferdie_client = ferdie.client.clone(); - let create_submit_bundle = |primary_number: BlockNumber| { - let primary_hash = ferdie_client.hash(primary_number).unwrap().unwrap(); - let execution_receipt = - crate::aux_schema::load_execution_receipt(&*bob.backend, primary_hash) - .expect("Failed to load execution receipt from the local aux_db") - .unwrap_or_else(|| { - panic!( - "The requested execution receipt for block {primary_number} does not exist" - ) - }); - - let mut opaque_bundle = bundle_template.clone(); - opaque_bundle.sealed_header.header.primary_number = primary_number; - opaque_bundle.sealed_header.header.primary_hash = primary_hash; - opaque_bundle.sealed_header.signature = alice_key - .pair() - .sign(opaque_bundle.sealed_header.pre_hash().as_ref()) - .into(); - opaque_bundle.receipt = execution_receipt; - - subspace_test_runtime::UncheckedExtrinsic::new_unsigned( - pallet_domains::Call::submit_bundle { opaque_bundle }.into(), - ) - .into() - }; - - let ferdie_client = ferdie.client.clone(); - let head_receipt_number = || { - let best_hash = ferdie_client.info().best_hash; - ferdie_client - .runtime_api() - .head_receipt_number(best_hash, DomainId::new(3u32)) - .expect("Failed to get head receipt number") - }; - - ferdie - .submit_transaction(create_submit_bundle(1)) - .await - .unwrap(); - ferdie - .submit_transaction(create_submit_bundle(2)) - .await - .unwrap(); - produce_blocks!(ferdie, bob, 1).await.unwrap(); - assert_eq!(head_receipt_number(), 2); + // let ferdie_client = ferdie.client.clone(); + // let create_submit_bundle = |primary_number: BlockNumber| { + // let primary_hash = ferdie_client.hash(primary_number).unwrap().unwrap(); + // let execution_receipt = + // crate::aux_schema::load_execution_receipt(&*bob.backend, primary_hash) + // .expect("Failed to load execution receipt from the local aux_db") + // .unwrap_or_else(|| { + // panic!( + // "The requested execution receipt for block {primary_number} does not exist" + // ) + // }); + + // let mut opaque_bundle = bundle_template.clone(); + // opaque_bundle.sealed_header.header.primary_number = primary_number; + // opaque_bundle.sealed_header.header.primary_hash = primary_hash; + // opaque_bundle.sealed_header.signature = alice_key + // .pair() + // .sign(opaque_bundle.sealed_header.pre_hash().as_ref()) + // .into(); + // opaque_bundle.receipt = execution_receipt; + + // subspace_test_runtime::UncheckedExtrinsic::new_unsigned( + // pallet_domains::Call::submit_bundle { opaque_bundle }.into(), + // ) + // .into() + // }; + + // TODO: Unlock once `head_receipt_number` API is usable. + // let ferdie_client = ferdie.client.clone(); + // let head_receipt_number = || { + // let best_hash = ferdie_client.info().best_hash; + // ferdie_client + // .runtime_api() + // .head_receipt_number(best_hash, DomainId::new(3u32)) + // .expect("Failed to get head receipt number") + // }; + + // ferdie + // .submit_transaction(create_submit_bundle(1)) + // .await + // .unwrap(); + // ferdie + // .submit_transaction(create_submit_bundle(2)) + // .await + // .unwrap(); + // produce_blocks!(ferdie, bob, 1).await.unwrap(); + // assert_eq!(head_receipt_number(), 2); } #[substrate_test_utils::test(flavor = "multi_thread")] diff --git a/domains/client/relayer/src/worker.rs b/domains/client/relayer/src/worker.rs index d7f4ced29c..1892084c5a 100644 --- a/domains/client/relayer/src/worker.rs +++ b/domains/client/relayer/src/worker.rs @@ -8,7 +8,6 @@ use sp_domains::DomainId; use sp_messenger::RelayerApi; use sp_runtime::scale_info::TypeInfo; use sp_runtime::traits::{CheckedSub, NumberFor, Zero}; -use sp_settlement::SettlementApi; use std::sync::Arc; /// Starts relaying system domain messages to other domains. @@ -62,81 +61,6 @@ pub async fn relay_system_domain_messages( } } -/// Starts relaying core domain messages to other domains. -/// If the either system domain or core domain node is in major sync, -/// worker waits waits until the sync is finished. -pub async fn relay_core_domain_messages( - relayer_id: RelayerId, - core_domain_client: Arc, - system_domain_client: Arc, - system_domain_sync_oracle: SDSO, - core_domain_sync_oracle: CDSO, - gossip_message_sink: GossipMessageSink, -) where - Block: BlockT, - PBlock: BlockT, - SBlock: BlockT, - Block::Hash: FullCodec, - NumberFor: FullCodec + TypeInfo, - NumberFor: From> + Into>, - SBlock::Hash: Into + From, - CDC: BlockchainEvents - + HeaderBackend - + AuxStore - + ProofProvider - + ProvideRuntimeApi, - CDC::Api: RelayerApi>, - SDC: HeaderBackend + ProvideRuntimeApi + ProofProvider, - SDC::Api: RelayerApi> - + SettlementApi, - SDSO: SyncOracle + Send, - CDSO: SyncOracle + Send, - RelayerId: Encode + Decode + Clone, -{ - let combined_sync_oracle = - CombinedSyncOracle::new(system_domain_sync_oracle, core_domain_sync_oracle); - - let relay_confirmation_depth = match Relayer::relay_confirmation_depth(&core_domain_client) { - Ok(depth) => depth, - Err(err) => { - tracing::error!(target: LOG_TARGET, ?err, "Failed to get confirmation depth"); - return; - } - }; - - let result = relay_domain_messages( - relayer_id, - relay_confirmation_depth, - core_domain_client, - |relayer_id, client, block_hash| { - Relayer::submit_messages_from_core_domain( - relayer_id, - client, - &system_domain_client, - block_hash, - &gossip_message_sink, - relay_confirmation_depth.into(), - ) - }, - combined_sync_oracle, - |domain_id, block_number| -> Result { - let api = system_domain_client.runtime_api(); - let at = system_domain_client.info().best_hash; - let oldest_tracked_number = api.oldest_receipt_number(at, domain_id)?; - // ensure block number is at least the oldest tracked number - Ok(block_number >= oldest_tracked_number.into()) - }, - ) - .await; - if let Err(err) = result { - tracing::error!( - target: LOG_TARGET, - ?err, - "Failed to start relayer for core domain" - ) - } -} - async fn relay_domain_messages( relayer_id: RelayerId, relay_confirmation_depth: NumberFor, diff --git a/domains/service/src/domain.rs b/domains/service/src/domain.rs index 79feaca34e..dbe7d7fcb5 100644 --- a/domains/service/src/domain.rs +++ b/domains/service/src/domain.rs @@ -32,7 +32,6 @@ use sp_domains::{DomainId, ExecutorApi}; use sp_messenger::{MessengerApi, RelayerApi}; use sp_offchain::OffchainWorkerApi; use sp_session::SessionKeys; -use sp_settlement::SettlementApi; use sp_transaction_pool::runtime_api::TaggedTransactionQueue; use std::fmt::{Debug, Display}; use std::marker::PhantomData; @@ -69,7 +68,7 @@ where + Send + Sync + 'static, - PClient::Api: ExecutorApi + SettlementApi, + PClient::Api: ExecutorApi, RuntimeApi: ConstructRuntimeApi> + Send + Sync @@ -160,7 +159,7 @@ where + Send + Sync + 'static, - PClient::Api: ExecutorApi + SettlementApi, + PClient::Api: ExecutorApi, RuntimeApi: ConstructRuntimeApi> + Send + Sync @@ -292,7 +291,7 @@ where + Send + Sync + 'static, - PClient::Api: ExecutorApi + SettlementApi, + PClient::Api: ExecutorApi, SC: SelectChain, IBNS: Stream, mpsc::Sender<()>)> + Send + 'static, CIBNS: Stream> + Send + 'static, @@ -427,11 +426,13 @@ where let spawn_essential = task_manager.spawn_essential_handle(); let (bundle_sender, _bundle_receiver) = tracing_unbounded("domain_bundle_stream", 100); - let domain_confirmation_depth = primary_chain_client - .runtime_api() - .receipts_pruning_depth(primary_chain_client.info().best_hash) - .map_err(|err| sc_service::error::Error::Application(Box::new(err)))? - .into(); + // let domain_confirmation_depth = primary_chain_client + // .runtime_api() + // .receipts_pruning_depth(primary_chain_client.info().best_hash) + // .map_err(|err| sc_service::error::Error::Application(Box::new(err)))? + // .into(); + // TODO: Implement when block tree is ready. + let domain_confirmation_depth = 256u32.into(); let executor = Executor::new( Box::new(task_manager.spawn_essential_handle()), diff --git a/domains/service/src/domain_tx_pre_validator.rs b/domains/service/src/domain_tx_pre_validator.rs index d8d7733014..1c297d72ae 100644 --- a/domains/service/src/domain_tx_pre_validator.rs +++ b/domains/service/src/domain_tx_pre_validator.rs @@ -6,9 +6,8 @@ use sc_transaction_pool_api::TransactionSource; use sp_api::ProvideRuntimeApi; use sp_blockchain::HeaderBackend; use sp_core::traits::SpawnNamed; -use sp_domains::DomainId; +use sp_domains::{DomainId, ExecutorApi}; use sp_runtime::traits::{Block as BlockT, NumberFor}; -use sp_settlement::SettlementApi; use std::marker::PhantomData; use std::sync::Arc; use subspace_transaction_pool::PreValidateTransaction; @@ -70,7 +69,7 @@ where NumberFor: From>, Client: ProvideRuntimeApi + Send + Sync, PClient: HeaderBackend + ProvideRuntimeApi + 'static, - PClient::Api: SettlementApi, + PClient::Api: ExecutorApi, SRE: StateRootExtractor + Send + Sync, { type Block = Block; diff --git a/test/subspace-test-runtime/src/lib.rs b/test/subspace-test-runtime/src/lib.rs index 4c3a83a08e..ac5ea9ed3a 100644 --- a/test/subspace-test-runtime/src/lib.rs +++ b/test/subspace-test-runtime/src/lib.rs @@ -1120,58 +1120,6 @@ impl_runtime_apis! { } } - impl sp_settlement::SettlementApi for Runtime { - fn execution_trace(domain_id: DomainId, receipt_hash: H256) -> Vec { - Settlement::receipts(domain_id, receipt_hash).map(|receipt| receipt.trace).unwrap_or_default() - } - - fn state_root( - domain_id: DomainId, - domain_block_number: NumberFor, - domain_block_hash: Hash, - ) -> Option { - Settlement::state_root((domain_id, domain_block_number, domain_block_hash)) - } - - fn primary_hash(domain_id: DomainId, domain_block_number: BlockNumber) -> Option { - Settlement::primary_hash(domain_id, domain_block_number) - } - - fn receipts_pruning_depth() -> BlockNumber { - ReceiptsPruningDepth::get() - } - - fn head_receipt_number(domain_id: DomainId) -> NumberFor { - Settlement::head_receipt_number(domain_id) - } - - fn oldest_receipt_number(domain_id: DomainId) -> NumberFor { - Settlement::oldest_receipt_number(domain_id) - } - - fn maximum_receipt_drift() -> NumberFor { - MaximumReceiptDrift::get() - } - - fn extract_receipts( - extrinsics: Vec<::Extrinsic>, - domain_id: DomainId, - ) -> Vec, ::Hash, domain_runtime_primitives::Hash>> { - extract_receipts(extrinsics, domain_id) - } - - fn extract_fraud_proofs( - extrinsics: Vec<::Extrinsic>, - domain_id: DomainId, - ) -> Vec, ::Hash>> { - extract_fraud_proofs(extrinsics, domain_id) - } - - fn submit_fraud_proof_unsigned(fraud_proof: FraudProof, ::Hash>) { - Domains::submit_fraud_proof_unsigned(fraud_proof) - } - } - impl sp_domains::transaction::PreValidationObjectApi for Runtime { fn extract_pre_validation_object( extrinsic: ::Extrinsic, From 82602ed203ac92f506ed3c8ee26341b45adeb229 Mon Sep 17 00:00:00 2001 From: Liu-Cheng Xu Date: Sun, 2 Jul 2023 20:50:25 +0800 Subject: [PATCH 2/4] Remove pallet-settlement and sp-settlement deps --- Cargo.lock | 12 ----- crates/pallet-domains/Cargo.toml | 2 - crates/pallet-domains/src/lib.rs | 54 ++++++++----------- crates/pallet-domains/src/tests.rs | 9 +--- crates/sc-consensus-fraud-proof/Cargo.toml | 1 - crates/subspace-fraud-proof/Cargo.toml | 1 - crates/subspace-runtime/Cargo.toml | 4 -- crates/subspace-runtime/src/domains.rs | 11 ++-- crates/subspace-runtime/src/lib.rs | 12 +---- crates/subspace-service/Cargo.toml | 1 - domains/client/block-preprocessor/Cargo.toml | 1 - domains/client/domain-executor/Cargo.toml | 1 - .../domain-executor/src/parent_chain.rs | 2 +- domains/client/domain-executor/src/tests.rs | 6 +-- domains/client/relayer/Cargo.toml | 1 - domains/pallets/messenger/src/mock.rs | 1 + domains/service/Cargo.toml | 1 - domains/service/src/domain.rs | 2 +- test/subspace-test-runtime/Cargo.toml | 4 -- test/subspace-test-runtime/src/lib.rs | 18 +++---- 20 files changed, 46 insertions(+), 98 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e5232354de..937e545ed7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2137,7 +2137,6 @@ dependencies = [ "sp-keyring", "sp-messenger", "sp-runtime", - "sp-settlement", "sp-state-machine", "subspace-core-primitives", "subspace-runtime-primitives", @@ -2204,7 +2203,6 @@ dependencies = [ "sp-keystore", "sp-messenger", "sp-runtime", - "sp-settlement", "sp-state-machine", "sp-trie", "subspace-core-primitives", @@ -2259,7 +2257,6 @@ dependencies = [ "sp-domains", "sp-messenger", "sp-runtime", - "sp-settlement", "tracing", ] @@ -2380,7 +2377,6 @@ dependencies = [ "sp-offchain", "sp-runtime", "sp-session", - "sp-settlement", "sp-transaction-pool", "subspace-core-primitives", "subspace-fraud-proof", @@ -6306,7 +6302,6 @@ dependencies = [ "frame-support", "frame-system", "log", - "pallet-settlement", "parity-scale-codec", "scale-info", "sp-core", @@ -8248,7 +8243,6 @@ dependencies = [ "sp-consensus", "sp-domains", "sp-runtime", - "sp-settlement", "subspace-fraud-proof", ] @@ -10631,7 +10625,6 @@ dependencies = [ "sp-keyring", "sp-messenger", "sp-runtime", - "sp-settlement", "sp-state-machine", "sp-trie", "subspace-runtime-primitives", @@ -10783,7 +10776,6 @@ dependencies = [ "pallet-offences-subspace", "pallet-rewards", "pallet-runtime-configs", - "pallet-settlement", "pallet-subspace", "pallet-sudo", "pallet-timestamp", @@ -10804,7 +10796,6 @@ dependencies = [ "sp-offchain", "sp-runtime", "sp-session", - "sp-settlement", "sp-std", "sp-transaction-pool", "sp-version", @@ -10881,7 +10872,6 @@ dependencies = [ "sp-offchain", "sp-runtime", "sp-session", - "sp-settlement", "sp-timestamp", "sp-transaction-pool", "sp-trie", @@ -10952,7 +10942,6 @@ dependencies = [ "pallet-object-store", "pallet-offences-subspace", "pallet-rewards", - "pallet-settlement", "pallet-subspace", "pallet-sudo", "pallet-timestamp", @@ -10973,7 +10962,6 @@ dependencies = [ "sp-offchain", "sp-runtime", "sp-session", - "sp-settlement", "sp-std", "sp-transaction-pool", "sp-version", diff --git a/crates/pallet-domains/Cargo.toml b/crates/pallet-domains/Cargo.toml index f67c2cf724..660a4764d8 100644 --- a/crates/pallet-domains/Cargo.toml +++ b/crates/pallet-domains/Cargo.toml @@ -17,7 +17,6 @@ frame-benchmarking = { version = "4.0.0-dev", default-features = false, git = "h frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } log = { version = "0.4.19", default-features = false } -pallet-settlement = { version = "0.1.0", default-features = false, path = "../pallet-settlement" } 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/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-domains = { version = "0.1.0", default-features = false, path = "../sp-domains" } @@ -39,7 +38,6 @@ std = [ "frame-support/std", "frame-system/std", "log/std", - "pallet-settlement/std", "scale-info/std", "sp-core/std", "sp-domains/std", diff --git a/crates/pallet-domains/src/lib.rs b/crates/pallet-domains/src/lib.rs index 91b43b1331..eb2b0ebc06 100644 --- a/crates/pallet-domains/src/lib.rs +++ b/crates/pallet-domains/src/lib.rs @@ -51,22 +51,38 @@ mod pallet { use frame_support::weights::Weight; use frame_support::{Identity, PalletError}; use frame_system::pallet_prelude::*; - use pallet_settlement::{Error as SettlementError, FraudProofError}; use sp_core::H256; use sp_domains::fraud_proof::FraudProof; use sp_domains::transaction::InvalidTransactionCode; use sp_domains::{ DomainId, ExecutorPublicKey, GenesisDomainRuntime, OpaqueBundle, RuntimeId, RuntimeType, }; - use sp_runtime::traits::{BlockNumberProvider, Zero}; + use sp_runtime::traits::{BlockNumberProvider, CheckEqual, MaybeDisplay, SimpleBitOps, Zero}; use sp_std::fmt::Debug; use sp_std::vec::Vec; use subspace_core_primitives::U256; #[pallet::config] - pub trait Config: frame_system::Config + pallet_settlement::Config { + pub trait Config: frame_system::Config { type RuntimeEvent: From> + IsType<::RuntimeEvent>; + /// Domain block hash type. + type DomainHash: Parameter + + Member + + MaybeSerializeDeserialize + + Debug + + MaybeDisplay + + SimpleBitOps + + Ord + + Default + + Copy + + CheckEqual + + sp_std::hash::Hash + + AsRef<[u8]> + + AsMut<[u8]> + + MaxEncodedLen + + Into; + /// Same with `pallet_subspace::Config::ConfirmationDepthK`. type ConfirmationDepthK: Get; @@ -160,19 +176,6 @@ mod pallet { Empty, } - impl From for Error { - #[inline] - fn from(error: SettlementError) -> Self { - match error { - SettlementError::MissingParent => { - Self::Bundle(BundleError::Receipt(ExecutionReceiptError::MissingParent)) - } - SettlementError::FraudProof(err) => Self::FraudProof(err), - SettlementError::UnavailablePrimaryBlockHash => Self::UnavailablePrimaryBlockHash, - } - } - } - impl From for Error { fn from(err: RuntimeRegistryError) -> Self { Error::RuntimeRegistry(err) @@ -186,7 +189,7 @@ mod pallet { /// Invalid bundle. Bundle(BundleError), /// Invalid fraud proof. - FraudProof(FraudProofError), + FraudProof, /// Runtime registry specific errors RuntimeRegistry(RuntimeRegistryError), } @@ -275,9 +278,7 @@ mod pallet { let domain_id = opaque_bundle.domain_id(); - // TODO: Implement the receipts processing v2. - // pallet_settlement::Pallet::::track_receipt(domain_id, &opaque_bundle.receipt) - // .map_err(Error::::from)?; + // TODO: Implement the block tree v2. let bundle_hash = opaque_bundle.hash(); @@ -313,8 +314,7 @@ mod pallet { log::trace!(target: "runtime::domains", "Processing fraud proof: {fraud_proof:?}"); - pallet_settlement::Pallet::::process_fraud_proof(fraud_proof) - .map_err(Error::::from)?; + // TODO: Implement fraud proof processing. Ok(()) } @@ -454,15 +454,7 @@ mod pallet { .build() } Call::submit_fraud_proof { fraud_proof } => { - if let Err(e) = - pallet_settlement::Pallet::::validate_fraud_proof(fraud_proof) - { - log::debug!( - target: "runtime::domains", - "Bad fraud proof: {fraud_proof:?}, error: {e:?}", - ); - return InvalidTransactionCode::FraudProof.into(); - } + // TODO: Validate fraud proof // TODO: proper tag value. unsigned_validity("SubspaceSubmitFraudProof", fraud_proof) diff --git a/crates/pallet-domains/src/tests.rs b/crates/pallet-domains/src/tests.rs index 6272202889..4789c37c1b 100644 --- a/crates/pallet-domains/src/tests.rs +++ b/crates/pallet-domains/src/tests.rs @@ -26,7 +26,6 @@ frame_support::construct_runtime!( UncheckedExtrinsic = UncheckedExtrinsic, { System: frame_system, - Settlement: pallet_settlement, Domains: pallet_domains, } ); @@ -92,6 +91,7 @@ impl Get for ConfirmationDepthK { impl pallet_domains::Config for Test { type RuntimeEvent = RuntimeEvent; + type DomainHash = sp_core::H256; type ConfirmationDepthK = ConfirmationDepthK; type DomainRuntimeUpgradeDelay = DomainRuntimeUpgradeDelay; type WeightInfo = pallet_domains::weights::SubstrateWeight; @@ -100,13 +100,6 @@ impl pallet_domains::Config for Test { type ExpectedBundlesPerInterval = ExpectedBundlesPerInterval; } -impl pallet_settlement::Config for Test { - type RuntimeEvent = RuntimeEvent; - type DomainHash = H256; - type MaximumReceiptDrift = MaximumReceiptDrift; - type ReceiptsPruningDepth = ReceiptsPruningDepth; -} - pub(crate) fn new_test_ext() -> sp_io::TestExternalities { let t = frame_system::GenesisConfig::default() .build_storage::() diff --git a/crates/sc-consensus-fraud-proof/Cargo.toml b/crates/sc-consensus-fraud-proof/Cargo.toml index b61b5e46f1..e5f7c1ecd0 100644 --- a/crates/sc-consensus-fraud-proof/Cargo.toml +++ b/crates/sc-consensus-fraud-proof/Cargo.toml @@ -18,5 +18,4 @@ sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", sp-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-domains = { version = "0.1.0", path = "../sp-domains" } sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } -sp-settlement = { version = "0.1.0", path = "../sp-settlement" } subspace-fraud-proof = { version = "0.1.0", path = "../subspace-fraud-proof" } diff --git a/crates/subspace-fraud-proof/Cargo.toml b/crates/subspace-fraud-proof/Cargo.toml index 5372d191cd..6f237f03d6 100644 --- a/crates/subspace-fraud-proof/Cargo.toml +++ b/crates/subspace-fraud-proof/Cargo.toml @@ -26,7 +26,6 @@ sp-domains = { version = "0.1.0", path = "../sp-domains" } sp-domain-digests = { version = "0.1.0", path = "../../domains/primitives/digests" } sp-messenger = { version = "0.1.0", path = "../../domains/primitives/messenger" } sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } -sp-settlement = { version = "0.1.0", path = "../sp-settlement" } sp-state-machine = { version = "0.28.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-trie = { version = "22.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } tracing = "0.1.37" diff --git a/crates/subspace-runtime/Cargo.toml b/crates/subspace-runtime/Cargo.toml index 12eb3e3bbd..1cee32bb37 100644 --- a/crates/subspace-runtime/Cargo.toml +++ b/crates/subspace-runtime/Cargo.toml @@ -31,7 +31,6 @@ pallet-feeds = { version = "0.1.0", default-features = false, path = "../pallet- pallet-grandpa-finality-verifier = { version = "0.1.0", default-features = false, path = "../pallet-grandpa-finality-verifier" } pallet-object-store = { version = "0.1.0", default-features = false, path = "../pallet-object-store" } pallet-offences-subspace = { version = "0.1.0", default-features = false, path = "../pallet-offences-subspace" } -pallet-settlement = { version = "0.1.0", default-features = false, path = "../pallet-settlement" } pallet-rewards = { version = "0.1.0", default-features = false, path = "../pallet-rewards" } pallet-runtime-configs = { version = "0.1.0", default-features = false, path = "../pallet-runtime-configs" } pallet-subspace = { version = "0.1.0", default-features = false, features = ["serde"], path = "../pallet-subspace" } @@ -53,7 +52,6 @@ sp-objects = { version = "0.1.0", default-features = false, path = "../sp-object sp-offchain = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-session = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } -sp-settlement = { version = "0.1.0", default-features = false, path = "../sp-settlement" } sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-transaction-pool = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-version = { version = "22.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } @@ -85,7 +83,6 @@ std = [ "pallet-grandpa-finality-verifier/std", "pallet-object-store/std", "pallet-offences-subspace/std", - "pallet-settlement/std", "pallet-rewards/std", "pallet-runtime-configs/std", "pallet-subspace/std", @@ -107,7 +104,6 @@ std = [ "sp-offchain/std", "sp-runtime/std", "sp-session/std", - "sp-settlement/std", "sp-std/std", "sp-transaction-pool/std", "sp-version/std", diff --git a/crates/subspace-runtime/src/domains.rs b/crates/subspace-runtime/src/domains.rs index 73dc9dc380..fc19e17e77 100644 --- a/crates/subspace-runtime/src/domains.rs +++ b/crates/subspace-runtime/src/domains.rs @@ -1,4 +1,4 @@ -use crate::{Block, BlockNumber, Domains, Hash, RuntimeCall, Settlement, UncheckedExtrinsic}; +use crate::{Block, BlockNumber, Domains, Hash, RuntimeCall, UncheckedExtrinsic}; use sp_consensus_subspace::digests::CompatibleDigestItem; use sp_consensus_subspace::FarmerPublicKey; use sp_domains::fraud_proof::FraudProof; @@ -26,6 +26,8 @@ pub(crate) fn extract_successful_bundles( .collect() } +// TODO: Remove when proceeding to fraud proof v2. +#[allow(unused)] pub(crate) fn extract_receipts( extrinsics: Vec, domain_id: DomainId, @@ -45,17 +47,18 @@ pub(crate) fn extract_receipts( .collect() } +// TODO: Remove when proceeding to fraud proof v2. +#[allow(unused)] pub(crate) fn extract_fraud_proofs( extrinsics: Vec, domain_id: DomainId, ) -> Vec> { - let successful_fraud_proofs = Settlement::successful_fraud_proofs(); + // TODO: Ensure fraud proof extrinsic is infallible. extrinsics .into_iter() .filter_map(|uxt| match uxt.function { RuntimeCall::Domains(pallet_domains::Call::submit_fraud_proof { fraud_proof }) - if fraud_proof.domain_id() == domain_id - && successful_fraud_proofs.contains(&fraud_proof.hash()) => + if fraud_proof.domain_id() == domain_id => { Some(fraud_proof) } diff --git a/crates/subspace-runtime/src/lib.rs b/crates/subspace-runtime/src/lib.rs index cbd0bc847b..fa4fad19d1 100644 --- a/crates/subspace-runtime/src/lib.rs +++ b/crates/subspace-runtime/src/lib.rs @@ -56,8 +56,7 @@ use sp_consensus_subspace::{ }; use sp_core::crypto::{ByteArray, KeyTypeId}; use sp_core::{OpaqueMetadata, H256}; -use sp_domains::fraud_proof::FraudProof; -use sp_domains::{DomainId, ExecutionReceipt, OpaqueBundle}; +use sp_domains::{DomainId, OpaqueBundle}; use sp_runtime::traits::{AccountIdLookup, BlakeTwo256, NumberFor}; use sp_runtime::transaction_validity::{TransactionSource, TransactionValidity}; use sp_runtime::{create_runtime_str, generic, AccountId32, ApplyExtrinsicResult, Perbill}; @@ -432,6 +431,7 @@ parameter_types! { impl pallet_domains::Config for Runtime { type RuntimeEvent = RuntimeEvent; + type DomainHash = domain_runtime_primitives::Hash; type ConfirmationDepthK = ConfirmationDepthK; type DomainRuntimeUpgradeDelay = DomainRuntimeUpgradeDelay; type WeightInfo = pallet_domains::weights::SubstrateWeight; @@ -440,13 +440,6 @@ impl pallet_domains::Config for Runtime { type ExpectedBundlesPerInterval = ExpectedBundlesPerInterval; } -impl pallet_settlement::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type DomainHash = domain_runtime_primitives::Hash; - type MaximumReceiptDrift = MaximumReceiptDrift; - type ReceiptsPruningDepth = ReceiptsPruningDepth; -} - parameter_types! { pub const BlockReward: Balance = SSC / (ExpectedVotesPerBlock::get() as Balance + 1); pub const VoteReward: Balance = SSC / (ExpectedVotesPerBlock::get() as Balance + 1); @@ -528,7 +521,6 @@ construct_runtime!( Feeds: pallet_feeds = 9, GrandpaFinalityVerifier: pallet_grandpa_finality_verifier = 10, ObjectStore: pallet_object_store = 11, - Settlement: pallet_settlement = 15, Domains: pallet_domains = 12, RuntimeConfigs: pallet_runtime_configs = 14, diff --git a/crates/subspace-service/Cargo.toml b/crates/subspace-service/Cargo.toml index 602a9e36a3..e4cda71d1f 100644 --- a/crates/subspace-service/Cargo.toml +++ b/crates/subspace-service/Cargo.toml @@ -64,7 +64,6 @@ sp-externalities = { version = "0.19.0", git = "https://github.com/subspace/subs sp-objects = { version = "0.1.0", path = "../sp-objects" } sp-offchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } -sp-settlement = { version = "0.1.0", path = "../sp-settlement" } sp-timestamp = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-transaction-pool = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-trie = { version = "22.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } diff --git a/domains/client/block-preprocessor/Cargo.toml b/domains/client/block-preprocessor/Cargo.toml index e1aed2856d..c02d68d1c7 100644 --- a/domains/client/block-preprocessor/Cargo.toml +++ b/domains/client/block-preprocessor/Cargo.toml @@ -25,7 +25,6 @@ sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", r sp-domains = { version = "0.1.0", path = "../../../crates/sp-domains" } sp-messenger = { version = "0.1.0", path = "../../primitives/messenger" } sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } -sp-settlement = { version = "0.1.0", path = "../../../crates/sp-settlement" } sp-state-machine = { version = "0.28.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } subspace-core-primitives = { version = "0.1.0", path = "../../../crates/subspace-core-primitives" } subspace-runtime-primitives = { version = "0.1.0", path = "../../../crates/subspace-runtime-primitives" } diff --git a/domains/client/domain-executor/Cargo.toml b/domains/client/domain-executor/Cargo.toml index 0b7c01b83c..28651ecbbe 100644 --- a/domains/client/domain-executor/Cargo.toml +++ b/domains/client/domain-executor/Cargo.toml @@ -32,7 +32,6 @@ sp-domain-digests = { version = "0.1.0", path = "../../primitives/digests" } sp-keystore = { version = "0.27.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-messenger = { version = "0.1.0", path = "../../primitives/messenger" } sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } -sp-settlement = { version = "0.1.0", path = "../../../crates/sp-settlement" } sp-state-machine = { version = "0.28.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-trie = { version = "22.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } subspace-core-primitives = { version = "0.1.0", path = "../../../crates/subspace-core-primitives" } diff --git a/domains/client/domain-executor/src/parent_chain.rs b/domains/client/domain-executor/src/parent_chain.rs index d82afd7b50..65095a1668 100644 --- a/domains/client/domain-executor/src/parent_chain.rs +++ b/domains/client/domain-executor/src/parent_chain.rs @@ -102,7 +102,7 @@ where fn oldest_receipt_number( &self, - at: PBlock::Hash, + _at: PBlock::Hash, ) -> Result, sp_api::ApiError> { // TODO: Implement when block tree is ready. Ok(0u32.into()) diff --git a/domains/client/domain-executor/src/tests.rs b/domains/client/domain-executor/src/tests.rs index 4c6dc0da0f..eff5a5f096 100644 --- a/domains/client/domain-executor/src/tests.rs +++ b/domains/client/domain-executor/src/tests.rs @@ -20,7 +20,6 @@ use sp_domains::{Bundle, DomainId, ExecutorApi}; use sp_runtime::generic::{BlockId, Digest, DigestItem}; use sp_runtime::traits::{BlakeTwo256, Header as HeaderT}; use sp_runtime::OpaqueExtrinsic; -use subspace_core_primitives::BlockNumber; use subspace_fraud_proof::invalid_state_transition_proof::ExecutionProver; use subspace_test_service::{ produce_block_with, produce_blocks, produce_blocks_until, MockPrimaryNode, @@ -36,6 +35,7 @@ fn number_of(primary_node: &MockPrimaryNode, block_hash: Hash) -> u32 { } #[substrate_test_utils::test(flavor = "multi_thread")] +#[ignore] async fn collected_receipts_should_be_on_the_same_branch_with_current_best_block() { let directory = TempDir::new().expect("Must be able to create temporary directory"); let _ = sc_cli::LoggerBuilder::new("runtime=debug").init(); @@ -789,8 +789,8 @@ async fn pallet_domains_unsigned_extrinsics_should_work() { // Get a bundle from alice's tx pool and used as bundle template. let (_, bundle) = ferdie.produce_slot_and_wait_for_bundle_submission().await; - let bundle_template = bundle.unwrap(); - let alice_key = Sr25519Keyring::Alice; + let _bundle_template = bundle.unwrap(); + let _alice_key = Sr25519Keyring::Alice; // Drop alice in order to control the execution chain by submitting the receipts manually later. drop(alice); diff --git a/domains/client/relayer/Cargo.toml b/domains/client/relayer/Cargo.toml index 358a4d7b97..0f0251298d 100644 --- a/domains/client/relayer/Cargo.toml +++ b/domains/client/relayer/Cargo.toml @@ -30,5 +30,4 @@ sp-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/subs sp-domains = { version = "0.1.0", path = "../../../crates/sp-domains" } sp-messenger = { version = "0.1.0", path = "../../primitives/messenger" } sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } -sp-settlement = { version = "0.1.0", path = "../../../crates/sp-settlement" } tracing = "0.1.37" diff --git a/domains/pallets/messenger/src/mock.rs b/domains/pallets/messenger/src/mock.rs index 18f2be954d..5ca21181ce 100644 --- a/domains/pallets/messenger/src/mock.rs +++ b/domains/pallets/messenger/src/mock.rs @@ -242,6 +242,7 @@ impl EndpointHandler for MockEndpoint { } } +// TODO: Remove as pallet_settlement has been removed. #[frame_support::pallet] #[allow(dead_code)] pub(crate) mod mock_pallet_settlement { diff --git a/domains/service/Cargo.toml b/domains/service/Cargo.toml index e8c705afef..9728a13aef 100644 --- a/domains/service/Cargo.toml +++ b/domains/service/Cargo.toml @@ -59,7 +59,6 @@ sp-messenger = { version = "0.1.0", path = "../../domains/primitives/messenger" sp-offchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-session = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } -sp-settlement = { version = "0.1.0", path = "../../crates/sp-settlement" } sp-transaction-pool = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } subspace-core-primitives = { version = "0.1.0", path = "../../crates/subspace-core-primitives" } subspace-fraud-proof = { version = "0.1.0", path = "../../crates/subspace-fraud-proof" } diff --git a/domains/service/src/domain.rs b/domains/service/src/domain.rs index dbe7d7fcb5..80c56e61c0 100644 --- a/domains/service/src/domain.rs +++ b/domains/service/src/domain.rs @@ -432,7 +432,7 @@ where // .map_err(|err| sc_service::error::Error::Application(Box::new(err)))? // .into(); // TODO: Implement when block tree is ready. - let domain_confirmation_depth = 256u32.into(); + let domain_confirmation_depth = 256u32; let executor = Executor::new( Box::new(task_manager.spawn_essential_handle()), diff --git a/test/subspace-test-runtime/Cargo.toml b/test/subspace-test-runtime/Cargo.toml index 5877a7b70b..f2930cad52 100644 --- a/test/subspace-test-runtime/Cargo.toml +++ b/test/subspace-test-runtime/Cargo.toml @@ -29,7 +29,6 @@ pallet-feeds = { version = "0.1.0", default-features = false, path = "../../crat pallet-grandpa-finality-verifier = { version = "0.1.0", default-features = false, path = "../../crates/pallet-grandpa-finality-verifier" } pallet-object-store = { version = "0.1.0", default-features = false, path = "../../crates/pallet-object-store" } pallet-offences-subspace = { version = "0.1.0", default-features = false, path = "../../crates/pallet-offences-subspace" } -pallet-settlement = { version = "0.1.0", default-features = false, path = "../../crates/pallet-settlement" } pallet-rewards = { version = "0.1.0", default-features = false, path = "../../crates/pallet-rewards" } pallet-subspace = { version = "0.1.0", default-features = false, features = ["serde"], path = "../../crates/pallet-subspace" } pallet-sudo = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } @@ -49,7 +48,6 @@ sp-objects = { version = "0.1.0", default-features = false, path = "../../crates sp-offchain = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-session = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } -sp-settlement = { version = "0.1.0", default-features = false, path = "../../crates/sp-settlement" } sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-transaction-pool = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-version = { version = "22.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } @@ -80,7 +78,6 @@ std = [ "pallet-grandpa-finality-verifier/std", "pallet-object-store/std", "pallet-offences-subspace/std", - "pallet-settlement/std", "pallet-rewards/std", "pallet-subspace/std", "pallet-sudo/std", @@ -101,7 +98,6 @@ std = [ "sp-offchain/std", "sp-runtime/std", "sp-session/std", - "sp-settlement/std", "sp-std/std", "sp-transaction-pool/std", "sp-version/std", diff --git a/test/subspace-test-runtime/src/lib.rs b/test/subspace-test-runtime/src/lib.rs index ac5ea9ed3a..605e0ec0f5 100644 --- a/test/subspace-test-runtime/src/lib.rs +++ b/test/subspace-test-runtime/src/lib.rs @@ -488,6 +488,7 @@ parameter_types! { impl pallet_domains::Config for Runtime { type RuntimeEvent = RuntimeEvent; + type DomainHash = domain_runtime_primitives::Hash; type ConfirmationDepthK = ConfirmationDepthK; type DomainRuntimeUpgradeDelay = DomainRuntimeUpgradeDelay; type WeightInfo = pallet_domains::weights::SubstrateWeight; @@ -496,13 +497,6 @@ impl pallet_domains::Config for Runtime { type ExpectedBundlesPerInterval = ExpectedBundlesPerInterval; } -impl pallet_settlement::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type DomainHash = domain_runtime_primitives::Hash; - type MaximumReceiptDrift = MaximumReceiptDrift; - type ReceiptsPruningDepth = ReceiptsPruningDepth; -} - parameter_types! { pub const BlockReward: Balance = SSC / (ExpectedVotesPerBlock::get() as Balance + 1); pub const VoteReward: Balance = SSC / (ExpectedVotesPerBlock::get() as Balance + 1); @@ -624,7 +618,6 @@ construct_runtime!( Feeds: pallet_feeds = 6, GrandpaFinalityVerifier: pallet_grandpa_finality_verifier = 13, ObjectStore: pallet_object_store = 10, - Settlement: pallet_settlement = 14, Domains: pallet_domains = 11, Vesting: orml_vesting = 7, @@ -867,6 +860,8 @@ fn extract_successful_bundles( .collect() } +// TODO: Remove when proceeding to fraud proof v2. +#[allow(unused)] fn extract_receipts( extrinsics: Vec, domain_id: DomainId, @@ -886,17 +881,18 @@ fn extract_receipts( .collect() } +// TODO: Remove when proceeding to fraud proof v2. +#[allow(unused)] fn extract_fraud_proofs( extrinsics: Vec, domain_id: DomainId, ) -> Vec, Hash>> { - let successful_fraud_proofs = Settlement::successful_fraud_proofs(); + // TODO: Ensure fraud proof extrinsic is infallible. extrinsics .into_iter() .filter_map(|uxt| match uxt.function { RuntimeCall::Domains(pallet_domains::Call::submit_fraud_proof { fraud_proof }) - if fraud_proof.domain_id() == domain_id - && successful_fraud_proofs.contains(&fraud_proof.hash()) => + if fraud_proof.domain_id() == domain_id => { Some(fraud_proof) } From e57dc5501dbee273438572c53d622fbaa3b97450 Mon Sep 17 00:00:00 2001 From: Liu-Cheng Xu Date: Sun, 2 Jul 2023 21:03:17 +0800 Subject: [PATCH 3/4] Delete unused codes in domain relayer --- domains/client/relayer/src/lib.rs | 189 +-------------------------- domains/client/relayer/src/worker.rs | 5 +- 2 files changed, 7 insertions(+), 187 deletions(-) diff --git a/domains/client/relayer/src/lib.rs b/domains/client/relayer/src/lib.rs index 01580ed68a..2d15e762b1 100644 --- a/domains/client/relayer/src/lib.rs +++ b/domains/client/relayer/src/lib.rs @@ -4,17 +4,16 @@ pub mod worker; use async_channel::TrySendError; use cross_domain_message_gossip::Message as GossipMessage; -use parity_scale_codec::{Decode, Encode, FullCodec}; -use sc_client_api::{AuxStore, HeaderBackend, ProofProvider, StorageProof}; +use parity_scale_codec::{Decode, Encode}; +use sc_client_api::{AuxStore, HeaderBackend, ProofProvider}; use sc_utils::mpsc::TracingUnboundedSender; use sp_api::ProvideRuntimeApi; use sp_domains::DomainId; use sp_messenger::messages::{ - CoreDomainStateRootStorage, CrossDomainMessage, DomainBlockInfo, Proof, - RelayerMessageWithStorageKey, RelayerMessagesWithStorageKey, + CrossDomainMessage, DomainBlockInfo, Proof, RelayerMessageWithStorageKey, + RelayerMessagesWithStorageKey, }; use sp_messenger::RelayerApi; -use sp_runtime::scale_info::TypeInfo; use sp_runtime::traits::{Block as BlockT, CheckedSub, Header as HeaderT, NumberFor, One, Zero}; use sp_runtime::ArithmeticError; use std::marker::PhantomData; @@ -96,15 +95,6 @@ where .map_err(|_| Error::UnableToFetchDomainId) } - pub(crate) fn relay_confirmation_depth( - client: &Arc, - ) -> Result, Error> { - let best_block_id = client.info().best_hash; - let api = client.runtime_api(); - api.relay_confirmation_depth(best_block_id) - .map_err(|_| Error::UnableToFetchRelayConfirmationDepth) - } - /// Constructs the proof for the given key using the system domain backend. fn construct_system_domain_storage_proof_for_key_at( system_domain_client: &Arc, @@ -131,45 +121,6 @@ where .ok_or(Error::ConstructStorageProof) } - /// Constructs the proof for the given key using the core domain backend. - fn construct_core_domain_storage_proof_for_key_at( - system_domain_info: DomainBlockInfo, - core_domain_client: &Arc, - block_hash: Block::Hash, - key: &[u8], - system_domain_state_root: SHash, - core_domain_proof: StorageProof, - ) -> Result, Error> - where - SNumber: Into>, - SHash: Into, - { - core_domain_client - .header(block_hash)? - .map(|header| (*header.number(), header.hash())) - .and_then(|(number, hash)| { - let proof = core_domain_client - .read_proof(block_hash, &mut [key].into_iter()) - .ok()?; - Some(Proof { - system_domain_block_info: DomainBlockInfo { - block_number: system_domain_info.block_number.into(), - block_hash: system_domain_info.block_hash.into(), - }, - system_domain_state_root: system_domain_state_root.into(), - core_domain_proof: Some(( - DomainBlockInfo { - block_number: number, - block_hash: hash, - }, - core_domain_proof, - )), - message_proof: proof, - }) - }) - .ok_or(Error::ConstructStorageProof) - } - fn construct_cross_domain_message_and_submit< Submitter: Fn(CrossDomainMessage, Block::Hash, Block::Hash>) -> Result<(), Error>, ProofConstructor: Fn(Block::Hash, &[u8]) -> Result, Block::Hash, Block::Hash>, Error>, @@ -297,138 +248,6 @@ where Ok(()) } - pub(crate) fn submit_messages_from_core_domain( - relayer_id: RelayerId, - core_domain_client: &Arc, - system_domain_client: &Arc, - confirmed_block_hash: Block::Hash, - gossip_message_sink: &GossipMessageSink, - relay_confirmation_depth: NumberFor, - ) -> Result<(), Error> - where - SBlock: BlockT, - Block::Hash: FullCodec, - NumberFor: FullCodec + TypeInfo, - NumberFor: From> + Into>, - SBlock::Hash: Into + From, - SDC: HeaderBackend + ProvideRuntimeApi + ProofProvider, - SDC::Api: RelayerApi>, - { - let core_domain_id = Self::domain_id(core_domain_client)?; - let core_domain_block_header = core_domain_client.expect_header(confirmed_block_hash)?; - let system_domain_api = system_domain_client.runtime_api(); - let best_system_domain_block_hash = system_domain_client.info().best_hash; - let best_system_domain_block_header = - system_domain_client.expect_header(best_system_domain_block_hash)?; - - // verify if the core domain number is K-deep on System domain client - if !system_domain_api - .domain_best_number(best_system_domain_block_hash, core_domain_id)? - .map( - |best_number| match best_number.checked_sub(&relay_confirmation_depth) { - None => false, - Some(best_confirmed) => { - best_confirmed >= (*core_domain_block_header.number()).into() - } - }, - ) - .unwrap_or(false) - { - return Err(Error::CoreDomainNonConfirmedOnSystemDomain); - } - - // verify if the state root is matching. - let core_domain_number = *core_domain_block_header.number(); - if !system_domain_api - .domain_state_root( - best_system_domain_block_hash, - core_domain_id, - core_domain_number.into(), - confirmed_block_hash.into(), - )? - .map(|state_root| state_root == (*core_domain_block_header.state_root()).into()) - .unwrap_or_else(|| { - // if this is genesis block, ignore as state root of genesis for core domain is not tracked on runtime - core_domain_number.is_zero() - }) - { - tracing::error!( - target: LOG_TARGET, - "Core domain state root mismatch at: Number: {:?}, Hash: {:?}", - core_domain_number, - confirmed_block_hash - ); - return Err(Error::CoreDomainStateRootInvalid); - } - - // fetch messages to be relayed - let core_domain_api = core_domain_client.runtime_api(); - let assigned_messages: RelayerMessagesWithStorageKey = core_domain_api - .relayer_assigned_messages(confirmed_block_hash, relayer_id) - .map_err(|_| Error::FetchAssignedMessages)?; - - let filtered_messages = - Self::filter_assigned_messages(core_domain_client, assigned_messages)?; - - // short circuit if the there are no messages to relay - if filtered_messages.outbox.is_empty() && filtered_messages.inbox_responses.is_empty() { - return Ok(()); - } - - // generate core domain proof that points to the state root of the core domain block on System domain. - let storage_key = - CoreDomainStateRootStorage::, Block::Hash, Block::Hash>::storage_key( - core_domain_id, - *core_domain_block_header.number(), - core_domain_block_header.hash(), - ); - - // construct storage proof for the core domain state root using system domain backend. - let core_domain_state_root_proof = system_domain_client.read_proof( - best_system_domain_block_hash, - &mut [storage_key.as_ref()].into_iter(), - )?; - - let system_domain_block_info = DomainBlockInfo { - block_number: *best_system_domain_block_header.number(), - block_hash: best_system_domain_block_hash, - }; - - Self::construct_cross_domain_message_and_submit( - confirmed_block_hash, - filtered_messages.outbox, - |block_hash, key| { - Self::construct_core_domain_storage_proof_for_key_at( - system_domain_block_info.clone(), - core_domain_client, - block_hash, - key, - *best_system_domain_block_header.state_root(), - core_domain_state_root_proof.clone(), - ) - }, - |msg| Self::gossip_outbox_message(core_domain_client, msg, gossip_message_sink), - )?; - - Self::construct_cross_domain_message_and_submit( - confirmed_block_hash, - filtered_messages.inbox_responses, - |block_id, key| { - Self::construct_core_domain_storage_proof_for_key_at( - system_domain_block_info.clone(), - core_domain_client, - block_id, - key, - *best_system_domain_block_header.state_root(), - core_domain_state_root_proof.clone(), - ) - }, - |msg| Self::gossip_inbox_message_response(core_domain_client, msg, gossip_message_sink), - )?; - - Ok(()) - } - /// Sends an Outbox message from src_domain to dst_domain. fn gossip_outbox_message( client: &Arc, diff --git a/domains/client/relayer/src/worker.rs b/domains/client/relayer/src/worker.rs index 1892084c5a..f3403af262 100644 --- a/domains/client/relayer/src/worker.rs +++ b/domains/client/relayer/src/worker.rs @@ -1,12 +1,11 @@ use crate::{BlockT, Error, GossipMessageSink, HeaderBackend, HeaderT, Relayer, LOG_TARGET}; use futures::StreamExt; -use parity_scale_codec::{Decode, Encode, FullCodec}; +use parity_scale_codec::{Decode, Encode}; use sc_client_api::{AuxStore, BlockchainEvents, ProofProvider}; use sp_api::{ApiError, ProvideRuntimeApi}; use sp_consensus::SyncOracle; use sp_domains::DomainId; use sp_messenger::RelayerApi; -use sp_runtime::scale_info::TypeInfo; use sp_runtime::traits::{CheckedSub, NumberFor, Zero}; use std::sync::Arc; @@ -197,6 +196,8 @@ where impl CombinedSyncOracle { /// Returns a new sync oracle that wraps system domain and core domain sync oracle. + // TODO: Remove or make use of it. + #[allow(unused)] fn new(system_domain_sync_oracle: SDSO, core_domain_sync_oracle: CDSO) -> Self { CombinedSyncOracle { system_domain_sync_oracle, From 2ee4d5baa0831e153be386e89ecc721bea372415 Mon Sep 17 00:00:00 2001 From: Liu-Cheng Xu Date: Sun, 2 Jul 2023 21:23:58 +0800 Subject: [PATCH 4/4] Delete pallet-settlement and sp-settlement --- Cargo.lock | 27 -- crates/pallet-settlement/Cargo.toml | 36 -- crates/pallet-settlement/src/lib.rs | 488 ---------------------------- crates/sp-settlement/Cargo.toml | 31 -- crates/sp-settlement/src/lib.rs | 72 ---- 5 files changed, 654 deletions(-) delete mode 100644 crates/pallet-settlement/Cargo.toml delete mode 100644 crates/pallet-settlement/src/lib.rs delete mode 100644 crates/sp-settlement/Cargo.toml delete mode 100644 crates/sp-settlement/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 937e545ed7..fd6c4aff7c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6661,21 +6661,6 @@ dependencies = [ "sp-trie", ] -[[package]] -name = "pallet-settlement" -version = "0.1.0" -dependencies = [ - "frame-support", - "frame-system", - "log", - "parity-scale-codec", - "scale-info", - "sp-core", - "sp-domains", - "sp-runtime", - "sp-std", -] - [[package]] name = "pallet-subspace" version = "0.1.0" @@ -10103,18 +10088,6 @@ dependencies = [ "sp-std", ] -[[package]] -name = "sp-settlement" -version = "0.1.0" -dependencies = [ - "parity-scale-codec", - "sp-api", - "sp-core", - "sp-domains", - "sp-runtime", - "sp-std", -] - [[package]] name = "sp-staking" version = "4.0.0-dev" diff --git a/crates/pallet-settlement/Cargo.toml b/crates/pallet-settlement/Cargo.toml deleted file mode 100644 index a0851f7ae2..0000000000 --- a/crates/pallet-settlement/Cargo.toml +++ /dev/null @@ -1,36 +0,0 @@ -[package] -name = "pallet-settlement" -version = "0.1.0" -authors = ["Subspace Labs "] -edition = "2021" -license = "Apache-2.0" -homepage = "https://subspace.network" -repository = "https://github.com/subspace/subspace" -description = "Subspace receipts pallet" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] - -[dependencies] -codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive"] } -frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } -frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } -log = { version = "0.4.19", 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/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } -sp-domains = { version = "0.1.0", default-features = false, path = "../sp-domains" } -sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } -sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } - -[features] -default = ["std"] -std = [ - "frame-support/std", - "frame-system/std", - "log/std", - "sp-core/std", - "sp-domains/std", - "sp-runtime/std", - "sp-std/std", -] -try-runtime = ["frame-support/try-runtime"] diff --git a/crates/pallet-settlement/src/lib.rs b/crates/pallet-settlement/src/lib.rs deleted file mode 100644 index 21b14b4f77..0000000000 --- a/crates/pallet-settlement/src/lib.rs +++ /dev/null @@ -1,488 +0,0 @@ -// Copyright (C) 2022 Subspace Labs, Inc. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! # Settlement Pallet -//! -//! This pallet provides the general common settlement functions needed by the consensus chain -//! and system domain, which mainly includes tracking the receipts and handling the fraud proofs -//! from the chain they secure. - -#![cfg_attr(not(feature = "std"), no_std)] - -use codec::{Decode, Encode}; -use frame_support::ensure; -use frame_support::traits::Get; -pub use pallet::*; -use sp_core::H256; -use sp_domains::fraud_proof::{FraudProof, InvalidStateTransitionProof, InvalidTransactionProof}; -use sp_domains::{DomainId, ExecutionReceipt}; -use sp_runtime::traits::{CheckedSub, One, Saturating, Zero}; -use sp_std::vec::Vec; - -#[frame_support::pallet] -mod pallet { - use frame_support::pallet_prelude::{StorageMap, StorageNMap, StorageValue, ValueQuery, *}; - use frame_support::PalletError; - use frame_system::pallet_prelude::*; - use sp_core::H256; - use sp_domains::{DomainId, ExecutionReceipt}; - use sp_runtime::traits::{CheckEqual, MaybeDisplay, SimpleBitOps}; - use sp_std::fmt::Debug; - use sp_std::vec::Vec; - - #[pallet::config] - pub trait Config: frame_system::Config { - /// Domain block hash type. - type DomainHash: Parameter - + Member - + MaybeSerializeDeserialize - + Debug - + MaybeDisplay - + SimpleBitOps - + Ord - + Default - + Copy - + CheckEqual - + sp_std::hash::Hash - + AsRef<[u8]> - + AsMut<[u8]> - + MaxEncodedLen - + Into; - - type RuntimeEvent: From> + IsType<::RuntimeEvent>; - - /// Maximum execution receipt drift. - /// - /// If the primary number of an execution receipt plus the maximum drift is bigger than the - /// best execution chain number, this receipt will be rejected as being too far in the - /// future. - #[pallet::constant] - type MaximumReceiptDrift: Get; - - /// Number of execution receipts kept in the state. - /// - /// This parameter specifies the fraud proof period. The challenge window is closed once - /// the receipts are pruned. - #[pallet::constant] - type ReceiptsPruningDepth: Get; - } - - #[pallet::pallet] - #[pallet::without_storage_info] - pub struct Pallet(_); - - /// Map of primary block number to primary block hash for tracking bounded receipts per domain. - /// - /// The oldest block hash will be pruned once the oldest receipt is pruned. However, if a - /// domain stalls, i.e., no receipts are included in the domain's parent chain for a long time, - /// the corresponding entry will grow indefinitely. - /// - /// TODO: there is a pitfall that any stalled domain can lead to an ubounded runtime storage - /// growth. - #[pallet::storage] - #[pallet::getter(fn primary_hash)] - pub type PrimaryBlockHash = StorageDoubleMap< - _, - Twox64Concat, - DomainId, - Twox64Concat, - T::BlockNumber, - T::Hash, - OptionQuery, - >; - - /// Stores the latest block number for which Execution receipt(s) are available for a given Domain. - #[pallet::storage] - #[pallet::getter(fn receipt_head)] - pub(super) type HeadReceiptNumber = - StorageMap<_, Twox64Concat, DomainId, T::BlockNumber, ValueQuery>; - - /// Block number of the oldest receipt stored in the state. - #[pallet::storage] - pub(super) type OldestReceiptNumber = - StorageMap<_, Twox64Concat, DomainId, T::BlockNumber, ValueQuery>; - - /// Mapping from the receipt hash to the corresponding verified execution receipt. - /// - /// The capacity of receipts stored in the state is [`Config::ReceiptsPruningDepth`], the older - /// ones will be pruned once the size of receipts exceeds this number. - #[pallet::storage] - #[pallet::getter(fn receipts)] - pub(super) type Receipts = StorageDoubleMap< - _, - Twox64Concat, - DomainId, - Twox64Concat, - H256, - ExecutionReceipt, - OptionQuery, - >; - - /// Mapping for tracking the receipt votes. - /// - /// (domain_id, domain_block_hash, receipt_hash) -> receipt_count - #[pallet::storage] - pub type ReceiptVotes = StorageNMap< - _, - ( - NMapKey, - NMapKey, - NMapKey, - ), - u32, - ValueQuery, - >; - - /// Mapping for tracking the domain state roots. - /// - /// (domain_id, domain_block_number, domain_block_hash) -> domain_state_root - #[pallet::storage] - #[pallet::getter(fn state_root)] - pub(super) type StateRoots = StorageNMap< - _, - ( - NMapKey, - NMapKey, - NMapKey, - ), - T::DomainHash, - OptionQuery, - >; - - /// Fraud proof processed successfully in current block. - #[pallet::storage] - pub(super) type SuccessfulFraudProofs = StorageValue<_, Vec, ValueQuery>; - - #[pallet::hooks] - impl Hooks> for Pallet { - fn on_initialize(_now: BlockNumberFor) -> Weight { - SuccessfulFraudProofs::::kill(); - T::DbWeight::get().writes(1) - } - } - - #[pallet::event] - #[pallet::generate_deposit(pub (super) fn deposit_event)] - pub enum Event { - /// A new domain receipt. - NewDomainReceipt { - domain_id: DomainId, - primary_number: T::BlockNumber, - primary_hash: T::Hash, - }, - /// An invalid state transition proof was processed. - InvalidStateTransitionProofProcessed { - domain_id: DomainId, - new_best_number: T::BlockNumber, - new_best_hash: T::Hash, - }, - } - - #[derive(TypeInfo, Encode, Decode, PalletError, Debug)] - pub enum FraudProofError { - /// Fraud proof is expired as the execution receipt has been pruned. - ExecutionReceiptPruned, - /// Trying to prove an receipt from the future. - ExecutionReceiptInFuture, - /// Unexpected hash type. - WrongHashType, - /// The execution receipt points to a block unknown to the history. - UnknownBlock, - /// This kind of fraud proof is still unimplemented. - Unimplemented, - } -} - -#[derive(Debug)] -pub enum Error { - /// The parent execution receipt is missing. - MissingParent, - /// Can not find the block hash of given primary block number. - UnavailablePrimaryBlockHash, - /// Invalid fraud proof. - FraudProof(FraudProofError), -} - -impl From for Error { - #[inline] - fn from(e: FraudProofError) -> Self { - Self::FraudProof(e) - } -} - -impl Pallet { - pub fn successful_fraud_proofs() -> Vec { - SuccessfulFraudProofs::::get() - } - - /// Returns the block number of the latest receipt. - pub fn head_receipt_number(domain_id: DomainId) -> T::BlockNumber { - >::get(domain_id) - } - - /// Initialize the head receipt on the domain creation. - pub fn initialize_head_receipt_number(domain_id: DomainId, created_at: T::BlockNumber) { - >::insert(domain_id, created_at) - } - - /// Returns the block number of the oldest receipt still being tracked in the state. - pub fn oldest_receipt_number(domain_id: DomainId) -> T::BlockNumber { - Self::finalized_receipt_number(domain_id) + One::one() - } - - /// Returns the state root of a domain at specific number and hash. - pub fn domain_state_root_at( - domain_id: DomainId, - number: T::BlockNumber, - hash: T::DomainHash, - ) -> Option { - StateRoots::::get((domain_id, number, hash)) - } - - /// Returns the block number of latest _finalized_ receipt. - pub fn finalized_receipt_number(domain_id: DomainId) -> T::BlockNumber { - let best_number = >::get(domain_id); - best_number.saturating_sub(T::ReceiptsPruningDepth::get()) - } - - /// Returns `true` if the primary block the receipt points to is part of the history. - pub fn point_to_valid_primary_block( - domain_id: DomainId, - receipt: &ExecutionReceipt, - ) -> bool { - Self::primary_hash(domain_id, receipt.primary_number) - .map(|hash| hash == receipt.primary_hash) - .unwrap_or(false) - } - - /// Initialize the genesis execution receipt - pub fn initialize_genesis_receipt(domain_id: DomainId, genesis_hash: T::Hash) { - let genesis_receipt = ExecutionReceipt { - primary_number: Zero::zero(), - primary_hash: genesis_hash, - domain_hash: T::DomainHash::default(), - trace: Vec::new(), - trace_root: Default::default(), - }; - Self::import_head_receipt(domain_id, &genesis_receipt); - // Explicitly initialize the oldest receipt number even not necessary as ValueQuery is used. - >::insert::<_, T::BlockNumber>(domain_id, Zero::zero()); - } - - /// Track the execution receipts for the domain - pub fn track_receipt( - domain_id: DomainId, - receipt: &ExecutionReceipt, - ) -> Result<(), Error> { - let oldest_receipt_number = >::get(domain_id); - let mut best_number = >::get(domain_id); - - let primary_number = receipt.primary_number; - - // Ignore the receipt if it has already been pruned. - if primary_number < oldest_receipt_number { - return Ok(()); - } - - if primary_number <= best_number { - // Either increase the vote for a known receipt or add a fork receipt at this height. - Self::import_receipt(domain_id, receipt); - } else if primary_number == best_number + One::one() { - Self::import_head_receipt(domain_id, receipt); - Self::remove_expired_receipts(domain_id, primary_number); - best_number += One::one(); - } else { - // Reject the entire Bundle due to the missing receipt(s) between [best_number, .., receipt.primary_number]. - return Err(Error::MissingParent); - } - Ok(()) - } - - /// Process a verified fraud proof. - pub fn process_fraud_proof( - fraud_proof: FraudProof, - ) -> Result<(), Error> { - let proof_hash = fraud_proof.hash(); - match fraud_proof { - FraudProof::InvalidStateTransition(proof) => { - Self::process_invalid_state_transition_proof(proof)? - } - FraudProof::InvalidTransaction(_proof) => { - // TODO: slash the executor accordingly. - } - _ => return Err(FraudProofError::Unimplemented.into()), - } - SuccessfulFraudProofs::::append(proof_hash); - Ok(()) - } - - fn process_invalid_state_transition_proof( - fraud_proof: InvalidStateTransitionProof, - ) -> Result<(), Error> { - // Revert the execution chain. - let domain_id = fraud_proof.domain_id; - let mut to_remove = >::get(domain_id); - - let new_best_number: T::BlockNumber = fraud_proof.parent_number.into(); - let new_best_hash = PrimaryBlockHash::::get(domain_id, new_best_number) - .ok_or(Error::UnavailablePrimaryBlockHash)?; - - >::insert(domain_id, new_best_number); - - while to_remove > new_best_number { - let block_hash = PrimaryBlockHash::::get(domain_id, to_remove) - .ok_or(Error::UnavailablePrimaryBlockHash)?; - for (receipt_hash, _) in >::drain_prefix((domain_id, block_hash)) { - if let Some(receipt) = >::take(domain_id, receipt_hash) { - StateRoots::::remove((domain_id, to_remove, receipt.domain_hash)) - } - } - to_remove -= One::one(); - } - // TODO: slash the executor accordingly. - Self::deposit_event(Event::InvalidStateTransitionProofProcessed { - domain_id, - new_best_number, - new_best_hash, - }); - Ok(()) - } - - pub fn validate_fraud_proof( - fraud_proof: &FraudProof, - ) -> Result<(), Error> { - match fraud_proof { - FraudProof::InvalidStateTransition(proof) => { - Self::validate_invalid_state_transition_proof(proof) - } - FraudProof::InvalidTransaction(proof) => { - Self::validate_invalid_transaction_proof(proof) - } - _ => Err(FraudProofError::Unimplemented.into()), - } - } - - fn validate_invalid_state_transition_proof( - fraud_proof: &InvalidStateTransitionProof, - ) -> Result<(), Error> { - let best_number = Self::head_receipt_number(fraud_proof.domain_id); - let to_prove: T::BlockNumber = (fraud_proof.parent_number + 1u32).into(); - ensure!( - to_prove > best_number.saturating_sub(T::ReceiptsPruningDepth::get()), - FraudProofError::ExecutionReceiptPruned - ); - - ensure!( - to_prove <= best_number, - FraudProofError::ExecutionReceiptInFuture - ); - - let primary_parent_hash = - T::Hash::decode(&mut fraud_proof.primary_parent_hash.encode().as_slice()) - .map_err(|_| FraudProofError::WrongHashType)?; - let parent_number: T::BlockNumber = fraud_proof.parent_number.into(); - ensure!( - Self::primary_hash(fraud_proof.domain_id, parent_number) == Some(primary_parent_hash), - FraudProofError::UnknownBlock - ); - - // TODO: prevent the spamming of fraud proof transaction. - - Ok(()) - } - - fn validate_invalid_transaction_proof( - fraud_proof: &InvalidTransactionProof, - ) -> Result<(), Error> { - let best_number = Self::head_receipt_number(fraud_proof.domain_id); - let to_prove: T::BlockNumber = fraud_proof.block_number.into(); - ensure!( - to_prove > best_number.saturating_sub(T::ReceiptsPruningDepth::get()), - FraudProofError::ExecutionReceiptPruned - ); - - ensure!( - to_prove <= best_number, - FraudProofError::ExecutionReceiptInFuture - ); - - Ok(()) - } -} - -impl Pallet { - /// Remove the expired receipts once the receipts cache is full. - fn remove_expired_receipts(domain_id: DomainId, primary_number: T::BlockNumber) { - if let Some(to_prune) = primary_number.checked_sub(&T::ReceiptsPruningDepth::get()) { - PrimaryBlockHash::::mutate_exists(domain_id, to_prune, |maybe_block_hash| { - if let Some(block_hash) = maybe_block_hash.take() { - for (receipt_hash, _) in - >::drain_prefix((domain_id, block_hash)) - { - >::remove(domain_id, receipt_hash); - } - } - }); - >::insert(domain_id, to_prune + One::one()); - let _ = >::clear_prefix((domain_id, to_prune), u32::MAX, None); - } - } - - /// Imports the receipt of the latest head of the domain. - /// Updates the receipt head of the domain accordingly. - fn import_head_receipt( - domain_id: DomainId, - receipt: &ExecutionReceipt, - ) { - Self::import_receipt(domain_id, receipt); - HeadReceiptNumber::::insert(domain_id, receipt.primary_number) - } - - /// Imports a receipt of domain. - /// Increments the receipt votes. - /// Assumes the receipt number is not pruned yet and inserts the a new receipt if not present. - fn import_receipt( - domain_id: DomainId, - execution_receipt: &ExecutionReceipt, - ) { - let primary_hash = execution_receipt.primary_hash; - let primary_number = execution_receipt.primary_number; - let receipt_hash = execution_receipt.hash(); - - // Track the fork receipt if it's not seen before. - if !>::contains_key(domain_id, receipt_hash) { - >::insert(domain_id, receipt_hash, execution_receipt); - if !primary_number.is_zero() { - let state_root = execution_receipt - .trace - .last() - .expect("There are at least 2 elements in trace after the genesis block; qed"); - - >::insert( - (domain_id, primary_number, execution_receipt.domain_hash), - state_root, - ); - } - Self::deposit_event(Event::NewDomainReceipt { - domain_id, - primary_number, - primary_hash, - }); - } - >::mutate((domain_id, primary_hash, receipt_hash), |count| { - *count += 1; - }); - } -} diff --git a/crates/sp-settlement/Cargo.toml b/crates/sp-settlement/Cargo.toml deleted file mode 100644 index 80887fd5c0..0000000000 --- a/crates/sp-settlement/Cargo.toml +++ /dev/null @@ -1,31 +0,0 @@ -[package] -name = "sp-settlement" -version = "0.1.0" -authors = ["Liu-Cheng Xu "] -edition = "2021" -license = "Apache-2.0" -homepage = "https://subspace.network" -repository = "https://github.com/subspace/subspace" -description = "Primitives for Receipts" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] - -[dependencies] -codec = { package = "parity-scale-codec", version = "3.1.2", default-features = false } -sp-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } -sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } -sp-domains = { version = "0.1.0", default-features = false, path = "../sp-domains" } -sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } -sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } - -[features] -default = ["std"] -std = [ - "codec/std", - "sp-api/std", - "sp-core/std", - "sp-domains/std", - "sp-runtime/std", - "sp-std/std", -] diff --git a/crates/sp-settlement/src/lib.rs b/crates/sp-settlement/src/lib.rs deleted file mode 100644 index 729f1e59c8..0000000000 --- a/crates/sp-settlement/src/lib.rs +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (C) 2023 Subspace Labs, Inc. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! Primitives for Receipts. - -#![cfg_attr(not(feature = "std"), no_std)] - -use codec::{Decode, Encode}; -use sp_core::H256; -use sp_domains::fraud_proof::FraudProof; -use sp_domains::{DomainId, ExecutionReceipt}; -use sp_runtime::traits::NumberFor; -use sp_std::vec::Vec; - -sp_api::decl_runtime_apis! { - pub trait SettlementApi { - /// Returns the trace of given domain receipt hash. - fn execution_trace(domain_id: DomainId, receipt_hash: H256) -> Vec; - - /// Returns the state root of given domain block. - fn state_root( - domain_id: DomainId, - domain_block_number: NumberFor, - domain_block_hash: Block::Hash, - ) -> Option; - - /// Returns the primary block hash for given domain block number. - fn primary_hash( - domain_id: DomainId, - domain_block_number: NumberFor, - ) -> Option; - - /// Returns the receipts pruning depth. - fn receipts_pruning_depth() -> NumberFor; - - /// Returns the best execution chain number. - fn head_receipt_number(domain_id: DomainId) -> NumberFor; - - /// Returns the block number of oldest execution receipt. - fn oldest_receipt_number(domain_id: DomainId) -> NumberFor; - - /// Returns the maximum receipt drift. - fn maximum_receipt_drift() -> NumberFor; - - /// Extract the receipts from the given extrinsics. - fn extract_receipts( - extrinsics: Vec, - domain_id: DomainId, - ) -> Vec, Block::Hash, DomainHash>>; - - /// Extract the fraud proofs from the given extrinsics. - fn extract_fraud_proofs( - extrinsics: Vec, - domain_id: DomainId, - ) -> Vec, Block::Hash>>; - - /// Submits the fraud proof via an unsigned extrinsic. - fn submit_fraud_proof_unsigned(fraud_proof: FraudProof, Block::Hash>); - } -}