Skip to content

Commit

Permalink
refactor domain specific host functions and ext factory and update fr…
Browse files Browse the repository at this point in the history
…aud proof verifier to use the extensions
  • Loading branch information
vedhavyas committed Feb 14, 2024
1 parent 2acab7c commit 4ee91fd
Show file tree
Hide file tree
Showing 17 changed files with 203 additions and 92 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/pallet-domains/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@ mod pallet {

/// Starting EVM chain ID for evm runtimes.
pub struct StartingEVMChainId;

impl Get<EVMChainId> for StartingEVMChainId {
fn get() -> EVMChainId {
// after looking at `https://chainlist.org/?testnets=false`
Expand Down
7 changes: 7 additions & 0 deletions crates/pallet-domains/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ frame_support::construct_runtime!(
type BlockNumber = u64;
type Hash = H256;
type AccountId = u128;

impl frame_system::Config for Test {
type BaseCallFilter = frame_support::traits::Everything;
type BlockWeights = ();
Expand Down Expand Up @@ -116,6 +117,7 @@ parameter_types! {
}

pub struct ConfirmationDepthK;

impl Get<BlockNumber> for ConfirmationDepthK {
fn get() -> BlockNumber {
10
Expand Down Expand Up @@ -193,6 +195,7 @@ impl frame_support::traits::Randomness<Hash, BlockNumber> for MockRandomness {
}

const SLOT_DURATION: u64 = 1000;

impl pallet_timestamp::Config for Test {
/// A timestamp: milliseconds since the unix epoch.
type Moment = Moment;
Expand All @@ -202,6 +205,7 @@ impl pallet_timestamp::Config for Test {
}

pub struct DummyStorageFee;

impl StorageFee<Balance> for DummyStorageFee {
fn transaction_byte_fee() -> Balance {
SSC
Expand All @@ -210,6 +214,7 @@ impl StorageFee<Balance> for DummyStorageFee {
}

pub struct DummyBlockSlot;

impl BlockSlot for DummyBlockSlot {
fn current_slot() -> sp_consensus_slots::Slot {
0u64.into()
Expand Down Expand Up @@ -253,6 +258,7 @@ impl pallet_domains::Config for Test {
}

pub struct ExtrinsicStorageFees;

impl domain_pallet_executive::ExtrinsicStorageFees<Test> for ExtrinsicStorageFees {
fn extract_signer(_xt: MockUncheckedExtrinsic<Test>) -> (Option<AccountId>, DispatchInfo) {
(None, DispatchInfo::default())
Expand Down Expand Up @@ -385,6 +391,7 @@ impl FraudProofHostFunctions for MockDomainFraudProofExtension {

fn execution_proof_check(
&self,
_domain_id: (u32, H256),
_pre_state_root: H256,
_encoded_proof: Vec<u8>,
_execution_method: &str,
Expand Down
66 changes: 60 additions & 6 deletions crates/sp-domains-fraud-proof/src/host_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,22 @@ use codec::{Decode, Encode};
use domain_block_preprocessor::inherents::extract_domain_runtime_upgrade_code;
use domain_block_preprocessor::stateless_runtime::StatelessRuntime;
use domain_runtime_primitives::{
CheckExtrinsicsValidityError, CHECK_EXTRINSICS_AND_DO_PRE_DISPATCH_METHOD_NAME,
BlockNumber, CheckExtrinsicsValidityError, CHECK_EXTRINSICS_AND_DO_PRE_DISPATCH_METHOD_NAME,
};
use hash_db::Hasher;
use sc_client_api::execution_extensions::ExtensionsFactory;
use sc_client_api::BlockBackend;
use sc_executor::RuntimeVersionOf;
use sp_api::ProvideRuntimeApi;
use sp_blockchain::HeaderBackend;
use sp_core::traits::{CodeExecutor, FetchRuntimeCode, RuntimeCode};
use sp_core::traits::{CallContext, CodeExecutor, FetchRuntimeCode, RuntimeCode};
use sp_core::H256;
use sp_domains::bundle_producer_election::BundleProducerElectionParams;
use sp_domains::{BundleProducerElectionApi, DomainId, DomainsApi, OperatorId};
use sp_runtime::traits::{Block as BlockT, Hash as HashT, Header as HeaderT};
use sp_externalities::Extensions;
use sp_runtime::traits::{Block as BlockT, Hash as HashT, Header as HeaderT, NumberFor};
use sp_runtime::OpaqueExtrinsic;
use sp_state_machine::{create_proof_check_backend, Error, OverlayedChanges, StateMachine};
use sp_std::vec::Vec;
use sp_trie::StorageProof;
use std::borrow::Cow;
Expand Down Expand Up @@ -53,6 +57,7 @@ pub trait FraudProofHostFunctions: Send + Sync {
/// Check the execution proof
fn execution_proof_check(
&self,
domain_block_id: (BlockNumber, H256),
pre_state_root: H256,
// TODO: implement `PassBy` for `sp_trie::StorageProof` in upstream to pass it directly here
encoded_proof: Vec<u8>,
Expand All @@ -78,16 +83,22 @@ impl FraudProofExtension {
pub struct FraudProofHostFunctionsImpl<Block, Client, DomainBlock, Executor> {
consensus_client: Arc<Client>,
executor: Arc<Executor>,
domain_extensions_factory: Box<dyn ExtensionsFactory<DomainBlock>>,
_phantom: PhantomData<(Block, DomainBlock)>,
}

impl<Block, Client, DomainBlock, Executor>
FraudProofHostFunctionsImpl<Block, Client, DomainBlock, Executor>
{
pub fn new(consensus_client: Arc<Client>, executor: Arc<Executor>) -> Self {
pub fn new(
consensus_client: Arc<Client>,
executor: Arc<Executor>,
domain_extensions_factory: Box<dyn ExtensionsFactory<DomainBlock>>,
) -> Self {
FraudProofHostFunctionsImpl {
consensus_client,
executor,
domain_extensions_factory,
_phantom: Default::default(),
}
}
Expand Down Expand Up @@ -327,7 +338,7 @@ where
&self,
consensus_block_hash: H256,
domain_id: DomainId,
domain_block_id: (u32, H256),
domain_block_id: (BlockNumber, H256),
domain_block_state_root: H256,
bundle_extrinsics: Vec<OpaqueExtrinsic>,
storage_proof: StorageProof,
Expand All @@ -337,6 +348,7 @@ where
let runtime_code = self.get_domain_runtime_code(consensus_block_hash, domain_id)?;

let raw_response = self.execution_proof_check(
domain_block_id,
domain_block_state_root,
storage_proof.encode(),
CHECK_EXTRINSICS_AND_DO_PRE_DISPATCH_METHOD_NAME,
Expand All @@ -362,6 +374,7 @@ where
Block::Hash: From<H256>,
DomainBlock: BlockT,
DomainBlock::Hash: From<H256> + Into<H256>,
NumberFor<DomainBlock>: From<BlockNumber>,
Client: BlockBackend<Block> + HeaderBackend<Block> + ProvideRuntimeApi<Block>,
Client::Api: DomainsApi<Block, DomainBlock::Header> + BundleProducerElectionApi<Block, Balance>,
Executor: CodeExecutor + RuntimeVersionOf,
Expand Down Expand Up @@ -516,6 +529,7 @@ where

fn execution_proof_check(
&self,
domain_block_id: (BlockNumber, H256),
pre_state_root: H256,
encoded_proof: Vec<u8>,
execution_method: &str,
Expand All @@ -532,15 +546,55 @@ where
heap_pages: None,
};

sp_state_machine::execution_proof_check::<<DomainBlock::Header as HeaderT>::Hashing, _>(
let (domain_block_number, domain_block_hash) = domain_block_id;
let mut domain_extensions = self
.domain_extensions_factory
.extensions_for(domain_block_hash.into(), domain_block_number.into());

execution_proof_check::<<DomainBlock::Header as HeaderT>::Hashing, _>(
pre_state_root.into(),
proof,
&mut Default::default(),
self.executor.as_ref(),
execution_method,
call_data,
&runtime_code,
&mut domain_extensions,
)
.ok()
}
}

#[allow(clippy::too_many_arguments)]
/// Executes the given proof using the runtime
/// The only difference between sp_state_machine::execution_proof_check is Extensions
pub(crate) fn execution_proof_check<H, Exec>(
root: H::Out,
proof: StorageProof,
overlay: &mut OverlayedChanges<H>,
exec: &Exec,
method: &str,
call_data: &[u8],
runtime_code: &RuntimeCode,
extensions: &mut Extensions,
) -> Result<Vec<u8>, Box<dyn Error>>
where
H: Hasher,
H::Out: Ord + 'static + codec::Codec,
Exec: CodeExecutor + Clone + 'static,
{
let trie_backend = create_proof_check_backend::<H>(root, proof)?;
let result = StateMachine::<_, H, Exec>::new(
&trie_backend,
overlay,
exec,
method,
call_data,
extensions,
runtime_code,
CallContext::Offchain,
)
.execute();

result
}
3 changes: 3 additions & 0 deletions crates/sp-domains-fraud-proof/src/runtime_interface.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#[cfg(feature = "std")]
use crate::FraudProofExtension;
use crate::{FraudProofVerificationInfoRequest, FraudProofVerificationInfoResponse};
use domain_runtime_primitives::BlockNumber;
use sp_core::H256;
use sp_domains::DomainId;
#[cfg(feature = "std")]
Expand Down Expand Up @@ -38,6 +39,7 @@ pub trait FraudProofRuntimeInterface {
/// Check the execution proof
fn execution_proof_check(
&mut self,
domain_block_id: (BlockNumber, H256),
pre_state_root: H256,
encoded_proof: Vec<u8>,
execution_method: &str,
Expand All @@ -47,6 +49,7 @@ pub trait FraudProofRuntimeInterface {
self.extension::<FraudProofExtension>()
.expect("No `FraudProofExtension` associated for the current context!")
.execution_proof_check(
domain_block_id,
pre_state_root,
encoded_proof,
execution_method,
Expand Down
11 changes: 9 additions & 2 deletions crates/sp-domains-fraud-proof/src/verification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::{
FraudProofVerificationInfoResponse, SetCodeExtrinsic,
};
use codec::{Decode, Encode};
use domain_runtime_primitives::BlockFees;
use domain_runtime_primitives::{BlockFees, BlockNumber};
use hash_db::Hasher;
use sp_core::storage::StorageKey;
use sp_core::H256;
Expand All @@ -21,7 +21,9 @@ use sp_domains::{
HeaderNumberFor, InboxedBundle, InvalidBundleType, OperatorPublicKey, SealedBundleHeader,
};
use sp_runtime::generic::Digest;
use sp_runtime::traits::{Block as BlockT, Hash, Header as HeaderT, NumberFor};
use sp_runtime::traits::{
Block as BlockT, Hash, Header as HeaderT, NumberFor, UniqueSaturatedInto,
};
use sp_runtime::{OpaqueExtrinsic, RuntimeAppPublic, SaturatedConversion};
use sp_std::vec::Vec;
use sp_trie::{LayoutV1, StorageProof};
Expand Down Expand Up @@ -219,6 +221,7 @@ where
CBlock::Hash: Into<H256>,
DomainHeader: HeaderT,
DomainHeader::Hash: Into<H256> + From<H256>,
DomainHeader::Number: UniqueSaturatedInto<BlockNumber> + From<BlockNumber>,
{
let InvalidStateTransitionProof {
domain_id,
Expand All @@ -241,6 +244,10 @@ where
.call_data::<CBlock, DomainHeader, Balance>(&bad_receipt, &bad_receipt_parent)?;

let execution_result = fraud_proof_runtime_interface::execution_proof_check(
(
bad_receipt_parent.domain_block_number.saturated_into(),
bad_receipt_parent.domain_block_hash.into(),
),
pre_state_root,
proof.encode(),
execution_phase.execution_method(),
Expand Down
2 changes: 1 addition & 1 deletion crates/sp-subspace-mmr/src/host_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use codec::Decode;
use sp_api::ProvideRuntimeApi;
use sp_blockchain::HeaderBackend;
use sp_core::H256;
use sp_mmr_primitives::{EncodableOpaqueLeaf, MmrApi, Proof};
pub use sp_mmr_primitives::{EncodableOpaqueLeaf, MmrApi, Proof};
use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor};
use std::marker::PhantomData;
use std::sync::Arc;
Expand Down
2 changes: 1 addition & 1 deletion crates/subspace-node/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ use crate::domain::cli::DomainKey;
use crate::domain::{DomainCli, DomainSubcommand};
use clap::Parser;
use domain_runtime_primitives::opaque::Block as DomainBlock;
use domain_service::HostFunctions as DomainHostFunctions;
use frame_benchmarking_cli::BenchmarkCmd;
use futures::future::TryFutureExt;
use sc_cli::{ChainSpec, SubstrateCli};
Expand All @@ -37,6 +36,7 @@ use serde_json::Value;
use sp_core::crypto::Ss58AddressFormat;
use subspace_proof_of_space::chia::ChiaTable;
use subspace_runtime::{Block, RuntimeApi};
use subspace_service::domains::HostFunctions as DomainHostFunctions;
use subspace_service::HostFunctions;
use tracing::warn;

Expand Down
83 changes: 83 additions & 0 deletions crates/subspace-service/src/domains.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
use sc_client_api::execution_extensions::ExtensionsFactory as ExtensionsFactoryT;
use sc_executor::RuntimeVersionOf;
use sp_api::ProvideRuntimeApi;
use sp_blockchain::HeaderBackend;
use sp_core::traits::CodeExecutor;
use sp_core::H256;
use sp_domains::DomainsApi;
use sp_externalities::Extensions;
use sp_messenger_host_functions::{MessengerApi, MessengerExtension, MessengerHostFunctionsImpl};
use sp_runtime::traits::{Block as BlockT, NumberFor};
use sp_subspace_mmr::host_functions::{MmrApi, SubspaceMmrExtension, SubspaceMmrHostFunctionsImpl};
use std::marker::PhantomData;
use std::sync::Arc;

/// Host functions required for Subspace domain
#[cfg(not(feature = "runtime-benchmarks"))]
pub type HostFunctions = (
sp_io::SubstrateHostFunctions,
sp_messenger_host_functions::HostFunctions,
sp_subspace_mmr::DomainHostFunctions,
);

/// Host functions required for Subspace domain
#[cfg(feature = "runtime-benchmarks")]
pub type HostFunctions = (
sp_io::SubstrateHostFunctions,
sp_messenger_host_functions::HostFunctions,
sp_subspace_mmr::DomainHostFunctions,
frame_benchmarking::benchmarking::HostFunctions,
);

/// Runtime executor for Domains
pub type RuntimeExecutor = sc_executor::WasmExecutor<HostFunctions>;

/// Extensions factory for subspace domains.
pub struct ExtensionsFactory<CClient, CBlock, Block, Executor> {
consensus_client: Arc<CClient>,
executor: Arc<Executor>,
_marker: PhantomData<(CBlock, Block)>,
}

impl<CClient, CBlock, Block, Executor> ExtensionsFactory<CClient, CBlock, Block, Executor> {
pub fn new(consensus_client: Arc<CClient>, executor: Arc<Executor>) -> Self {
Self {
consensus_client,
executor,
_marker: Default::default(),
}
}
}

impl<CClient, CBlock, Block, Executor> ExtensionsFactoryT<Block>
for ExtensionsFactory<CClient, CBlock, Block, Executor>
where
Block: BlockT,
CBlock: BlockT,
CBlock::Hash: From<H256>,
CClient: HeaderBackend<CBlock> + ProvideRuntimeApi<CBlock> + 'static,
CClient::Api: MmrApi<CBlock, H256, NumberFor<CBlock>>
+ MessengerApi<CBlock, NumberFor<CBlock>>
+ DomainsApi<CBlock, Block::Header>,
Executor: CodeExecutor + RuntimeVersionOf,
{
fn extensions_for(
&self,
_block_hash: Block::Hash,
_block_number: NumberFor<Block>,
) -> Extensions {
let mut exts = Extensions::new();
exts.register(SubspaceMmrExtension::new(Arc::new(
SubspaceMmrHostFunctionsImpl::<CBlock, _>::new(self.consensus_client.clone()),
)));

exts.register(MessengerExtension::new(Arc::new(
MessengerHostFunctionsImpl::<CBlock, _, Block, _>::new(
self.consensus_client.clone(),
self.executor.clone(),
),
)));

exts
}
}
Loading

0 comments on commit 4ee91fd

Please sign in to comment.