Skip to content

Commit

Permalink
derive domain timestamp extrinsic through host function
Browse files Browse the repository at this point in the history
  • Loading branch information
vedhavyas committed Oct 3, 2023
1 parent e5e77fa commit 73c2e39
Show file tree
Hide file tree
Showing 22 changed files with 212 additions and 110 deletions.
4 changes: 4 additions & 0 deletions Cargo.lock

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

19 changes: 11 additions & 8 deletions crates/pallet-domains/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ use sp_domains::{
OperatorPublicKey, ProofOfElection, RuntimeId, DOMAIN_EXTRINSICS_SHUFFLING_SEED_SUBJECT,
EMPTY_EXTRINSIC_ROOT,
};
use sp_domains_fraud_proof::fraud_proof_runtime_interface::derive_domain_timestamp_extrinsic;
use sp_runtime::traits::{BlakeTwo256, CheckedSub, Hash, One, Zero};
use sp_runtime::{RuntimeAppPublic, SaturatedConversion, Saturating};
use sp_std::boxed::Box;
Expand Down Expand Up @@ -141,13 +142,13 @@ mod pallet {
use frame_support::{Identity, PalletError};
use frame_system::pallet_prelude::*;
use sp_core::H256;
use sp_domains::fraud_proof::{DeriveExtrinsics, FraudProof, StorageKeys};
use sp_domains::fraud_proof::{FraudProof, StorageKeys};
use sp_domains::transaction::InvalidTransactionCode;
use sp_domains::{
BundleDigest, DomainId, EpochIndex, GenesisDomain, OperatorId, ReceiptHash, RuntimeId,
RuntimeType,
};
use sp_domains_fraud_proof::get_consensus_state_root;
use sp_domains_fraud_proof::fraud_proof_runtime_interface::get_consensus_state_root;
use sp_runtime::traits::{
AtLeast32BitUnsigned, BlockNumberProvider, Bounded, CheckEqual, CheckedAdd, Hash,
MaybeDisplay, One, SimpleBitOps, Zero,
Expand All @@ -160,7 +161,6 @@ mod pallet {
use sp_std::vec;
use sp_std::vec::Vec;
use subspace_core_primitives::U256;
use subspace_runtime_primitives::Moment;

#[pallet::config]
pub trait Config: frame_system::Config {
Expand Down Expand Up @@ -292,9 +292,6 @@ mod pallet {
/// Trait impl to fetch storage keys.
type StorageKeys: StorageKeys;

/// Derive extrinsics trait impl.
type DeriveExtrinsics: DeriveExtrinsics<Moment>;

/// Converts H256 to T::Hash.
/// This is required since T::Hash cannot be derived from H256 due to missing trait bounds.
fn h256_to_hash(hash: H256) -> Self::Hash;
Expand Down Expand Up @@ -1532,8 +1529,14 @@ impl<T: Config> Pallet<T> {
BalanceOf<T>,
T::Hashing,
T::StorageKeys,
T::DeriveExtrinsics,
>(consensus_state_root, bad_receipt, proof)
_,
T::DomainHashing,
>(
consensus_state_root,
bad_receipt,
proof,
derive_domain_timestamp_extrinsic,
)
.map_err(FraudProofError::InvalidExtrinsicRootFraudProof)?;
}
_ => {}
Expand Down
21 changes: 12 additions & 9 deletions crates/pallet-domains/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,14 +218,6 @@ impl pallet_timestamp::Config for Test {
type WeightInfo = ();
}

pub struct DeriveExtrinsics;
impl sp_domains::fraud_proof::DeriveExtrinsics<Moment> for DeriveExtrinsics {
fn derive_timestamp_extrinsic(now: Moment) -> Vec<u8> {
UncheckedExtrinsic::new_unsigned(pallet_timestamp::Call::<Test>::set { now }.into())
.encode()
}
}

impl pallet_domains::Config for Test {
type RuntimeEvent = RuntimeEvent;
type DomainNumber = BlockNumber;
Expand All @@ -252,7 +244,6 @@ impl pallet_domains::Config for Test {
type MaxPendingStakingOperation = MaxPendingStakingOperation;
type Randomness = MockRandomness;
type StorageKeys = StorageKeys;
type DeriveExtrinsics = DeriveExtrinsics;

fn h256_to_hash(hash: H256) -> Self::Hash {
hash
Expand All @@ -273,6 +264,18 @@ impl FraudProofHostFunctions for MockDomainFraudProofExtension {
fn get_consensus_state_root(&self, _consensus_block_hash: H256) -> Option<H256> {
Some(H256::default())
}

fn derive_domain_timestamp_extrinsic(
&self,
_consensus_block_hash: H256,
_domain_id: DomainId,
now: Moment,
) -> Option<Vec<u8>> {
Some(
UncheckedExtrinsic::new_unsigned(pallet_timestamp::Call::<Test>::set { now }.into())
.encode(),
)
}
}

pub(crate) fn new_test_ext_with_extensions() -> sp_io::TestExternalities {
Expand Down
8 changes: 7 additions & 1 deletion crates/sp-domains-fraud-proof/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,30 @@ include = [

[dependencies]
codec = { package = "parity-scale-codec", version = "3.6.5", default-features = false, features = ["derive"] }
domain-block-preprocessor = { version = "0.1.0", default-features = false, path = "../../domains/client/block-preprocessor", optional = true }
sp-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "c90d6edfd8c63168eff0dce6f2ace4d66dd139f7" }
sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/polkadot-sdk", rev = "c90d6edfd8c63168eff0dce6f2ace4d66dd139f7", optional = true }
sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "c90d6edfd8c63168eff0dce6f2ace4d66dd139f7" }
sp-domains = { version = "0.1.0", default-features = false, path = "../sp-domains" }
sp-externalities = { version = "0.19.0", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "c90d6edfd8c63168eff0dce6f2ace4d66dd139f7" }
sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "c90d6edfd8c63168eff0dce6f2ace4d66dd139f7" }
sp-runtime-interface = { version = "17.0.0", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "c90d6edfd8c63168eff0dce6f2ace4d66dd139f7" }
sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "c90d6edfd8c63168eff0dce6f2ace4d66dd139f7" }
subspace-runtime-primitives = { version = "0.1.0", default-features = false, path = "../subspace-runtime-primitives" }

[features]
default = ["std"]
std = [
"codec/std",
"domain-block-preprocessor",
"sp-api/std",
"sp-blockchain",
"sp-core/std",
"sp-domains/std",
"sp-externalities/std",
"sp-runtime/std",
"sp-runtime-interface/std",
"sp-std/std"
"sp-std/std",
"subspace-runtime-primitives/std"
]
runtime-benchmarks = []
66 changes: 58 additions & 8 deletions crates/sp-domains-fraud-proof/src/host_functions.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,27 @@
use sp_api::BlockT;
use codec::Encode;
use domain_block_preprocessor::runtime_api::InherentExtrinsicConstructor;
use domain_block_preprocessor::runtime_api_light::RuntimeApiLight;
use sp_api::{BlockT, ProvideRuntimeApi};
use sp_blockchain::HeaderBackend;
use sp_core::traits::CodeExecutor;
use sp_core::H256;
use sp_runtime::traits::Header;
use sp_domains::{DomainId, DomainsApi};
use sp_runtime::traits::{Header, NumberFor};
use std::marker::PhantomData;
use std::sync::Arc;
use subspace_runtime_primitives::Moment;

/// Trait to query and verify Domains Fraud proof.
pub trait FraudProofHostFunctions: Send + Sync {
/// Returns the consensus state root for a given consensus block hash.
fn get_consensus_state_root(&self, consensus_block_hash: H256) -> Option<H256>;
/// Returns an encoded domain timestamp extrinsic.
fn derive_domain_timestamp_extrinsic(
&self,
consensus_block_hash: H256,
domain_id: DomainId,
moment: Moment,
) -> Option<Vec<u8>>;
}

sp_externalities::decl_extension! {
Expand All @@ -24,25 +37,33 @@ impl FraudProofExtension {
}

/// Trait Impl to query and verify Domains Fraud proof.
pub struct FraudProofHostFunctionsImpl<Block, Client> {
pub struct FraudProofHostFunctionsImpl<Block, Client, DomainBlock, Executor> {
consensus_client: Arc<Client>,
_phantom: PhantomData<Block>,
executor: Arc<Executor>,
_phantom: PhantomData<(Block, DomainBlock)>,
}

impl<Block, Client> FraudProofHostFunctionsImpl<Block, Client> {
pub fn new(consensus_client: Arc<Client>) -> Self {
impl<Block, Client, DomainBlock, Executor>
FraudProofHostFunctionsImpl<Block, Client, DomainBlock, Executor>
{
pub fn new(consensus_client: Arc<Client>, executor: Arc<Executor>) -> Self {
FraudProofHostFunctionsImpl {
consensus_client,
executor,
_phantom: Default::default(),
}
}
}

impl<Block, Client> FraudProofHostFunctions for FraudProofHostFunctionsImpl<Block, Client>
impl<Block, Client, DomainBlock, Executor> FraudProofHostFunctions
for FraudProofHostFunctionsImpl<Block, Client, DomainBlock, Executor>
where
Block: BlockT,
Block::Hash: From<H256> + Into<H256>,
Client: HeaderBackend<Block>,
DomainBlock: BlockT,
Client: HeaderBackend<Block> + ProvideRuntimeApi<Block>,
Client::Api: DomainsApi<Block, NumberFor<DomainBlock>, DomainBlock::Hash>,
Executor: CodeExecutor,
{
fn get_consensus_state_root(&self, consensus_block_hash: H256) -> Option<H256> {
let state_root = self
Expand All @@ -52,4 +73,33 @@ where
.map(|header| *header.state_root())?;
Some(state_root.into())
}

fn derive_domain_timestamp_extrinsic(
&self,
consensus_block_hash: H256,
domain_id: DomainId,
timestamp: Moment,
) -> Option<Vec<u8>> {
let runtime_api = self.consensus_client.runtime_api();
let consensus_block_hash = consensus_block_hash.into();
let runtime_code = runtime_api
.domain_runtime_code(consensus_block_hash, domain_id)
.ok()??;

let domain_runtime_api_light =
RuntimeApiLight::new(self.executor.clone(), runtime_code.into());

let domain_timestamp_extrinsic =
InherentExtrinsicConstructor::<DomainBlock>::construct_timestamp_inherent_extrinsic(
&domain_runtime_api_light,
// We do not care about the domain hash since this is stateless call into
// domain runtime,
Default::default(),
timestamp,
)
.ok()?
.encode();

Some(domain_timestamp_extrinsic)
}
}
2 changes: 1 addition & 1 deletion crates/sp-domains-fraud-proof/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@ mod runtime_interface;
pub use host_functions::{
FraudProofExtension, FraudProofHostFunctions, FraudProofHostFunctionsImpl,
};
pub use runtime_interface::fraud_proof_runtime_interface::get_consensus_state_root;
pub use runtime_interface::fraud_proof_runtime_interface;
#[cfg(feature = "std")]
pub use runtime_interface::fraud_proof_runtime_interface::HostFunctions;
14 changes: 14 additions & 0 deletions crates/sp-domains-fraud-proof/src/runtime_interface.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
#[cfg(feature = "std")]
use crate::FraudProofExtension;
use sp_core::H256;
use sp_domains::DomainId;
#[cfg(feature = "std")]
use sp_externalities::ExternalitiesExt;
use sp_runtime_interface::runtime_interface;
use sp_std::vec::Vec;
use subspace_runtime_primitives::Moment;

/// Domain fraud proof related runtime interface
#[runtime_interface]
Expand All @@ -13,4 +16,15 @@ pub trait FraudProofRuntimeInterface {
.expect("No `FraudProofExtension` associated for the current context!")
.get_consensus_state_root(consensus_block_hash)
}

fn derive_domain_timestamp_extrinsic(
&mut self,
consensus_block_hash: H256,
domain_id: DomainId,
timestamp: Moment,
) -> Option<Vec<u8>> {
self.extension::<FraudProofExtension>()
.expect("No `FraudProofExtension` associated for the current context!")
.derive_domain_timestamp_extrinsic(consensus_block_hash, domain_id, timestamp)
}
}
2 changes: 2 additions & 0 deletions crates/sp-domains/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ sp-externalities = { version = "0.19.0", default-features = false, git = "https:
sp-inherents = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "c90d6edfd8c63168eff0dce6f2ace4d66dd139f7" }
sp-keystore = { version = "0.27.0", git = "https://github.com/subspace/polkadot-sdk", rev = "c90d6edfd8c63168eff0dce6f2ace4d66dd139f7", optional = true }
sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "c90d6edfd8c63168eff0dce6f2ace4d66dd139f7" }
sp-runtime-interface = { version = "17.0.0", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "c90d6edfd8c63168eff0dce6f2ace4d66dd139f7" }
sp-state-machine = { version = "0.28.0", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "c90d6edfd8c63168eff0dce6f2ace4d66dd139f7" }
sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "c90d6edfd8c63168eff0dce6f2ace4d66dd139f7" }
sp-trie = { version = "22.0.0", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "c90d6edfd8c63168eff0dce6f2ace4d66dd139f7" }
Expand Down Expand Up @@ -69,6 +70,7 @@ std = [
"sp-inherents/std",
"sp-keystore",
"sp-runtime/std",
"sp-runtime-interface/std",
"sp-state-machine/std",
"sp-std/std",
"sp-trie/std",
Expand Down
11 changes: 3 additions & 8 deletions crates/sp-domains/src/fraud_proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,6 @@ impl ExecutionPhase {
}
}

/// Trait to derive domain extrinsics such as timestamp on Consensus chain.
pub trait DeriveExtrinsics<Moment> {
/// Derives pallet_timestamp::set extrinsic.
fn derive_timestamp_extrinsic(moment: Moment) -> Vec<u8>;
}

/// Error type of fraud proof verification on consensus node.
#[derive(Debug)]
#[cfg_attr(feature = "thiserror", derive(thiserror::Error))]
Expand Down Expand Up @@ -436,11 +430,12 @@ pub enum ExtrinsicDigest {
impl ExtrinsicDigest {
pub fn new<Layout: TrieLayout>(ext: Vec<u8>) -> Self
where
Layout::Hash: Hasher<Out = H256>,
Layout::Hash: Hasher,
<Layout::Hash as Hasher>::Out: Into<H256>,
{
if let Some(threshold) = Layout::MAX_INLINE_VALUE {
if ext.len() >= threshold as usize {
ExtrinsicDigest::Hash(Layout::Hash::hash(&ext))
ExtrinsicDigest::Hash(Layout::Hash::hash(&ext).into())
} else {
ExtrinsicDigest::Data(ext)
}
Expand Down
6 changes: 6 additions & 0 deletions crates/sp-domains/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ use sp_runtime::traits::{
BlakeTwo256, Block as BlockT, CheckedAdd, Hash as HashT, NumberFor, Zero,
};
use sp_runtime::{DigestItem, OpaqueExtrinsic, Percent};
use sp_runtime_interface::pass_by;
use sp_runtime_interface::pass_by::PassBy;
use sp_std::vec::Vec;
use sp_weights::Weight;
use subspace_core_primitives::crypto::blake2b_256_hash;
Expand Down Expand Up @@ -163,6 +165,10 @@ impl DomainId {
}
}

impl PassBy for DomainId {
type PassBy = pass_by::Codec<Self>;
}

#[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone)]
pub struct BundleHeader<Number, Hash, DomainNumber, DomainHash, Balance> {
/// Proof of bundle producer election.
Expand Down
Loading

0 comments on commit 73c2e39

Please sign in to comment.