Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

XDM with MMR proofs: 1 #2508

Merged
merged 10 commits into from
Feb 23, 2024
40 changes: 40 additions & 0 deletions Cargo.lock

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

5 changes: 5 additions & 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 Expand Up @@ -2005,6 +2006,10 @@ impl<T: Config> Pallet<T> {
) -> Option<ReceiptHashFor<T>> {
BlockTree::<T>::get(domain_id, domain_number)
}

pub fn confirmed_domain_block_storage_key(domain_id: DomainId) -> Vec<u8> {
LatestConfirmedDomainBlock::<T>::hashed_key_for(domain_id)
}
}

impl<T> Pallet<T>
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
Loading
Loading