Skip to content

Commit

Permalink
apply review suggestions
Browse files Browse the repository at this point in the history
  • Loading branch information
vedhavyas committed Oct 10, 2023
1 parent cea9717 commit 8a20edc
Show file tree
Hide file tree
Showing 6 changed files with 159 additions and 67 deletions.
44 changes: 37 additions & 7 deletions crates/pallet-domains/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,11 @@ use sp_domains::{
OperatorPublicKey, ProofOfElection, RuntimeId, DOMAIN_EXTRINSICS_SHUFFLING_SEED_SUBJECT,
EMPTY_EXTRINSIC_ROOT,
};
use sp_domains_fraud_proof::fraud_proof_runtime_interface::get_invalid_domain_extrinsic_root_info;
use sp_domains_fraud_proof::fraud_proof_runtime_interface::get_fraud_proof_verification_info;
use sp_domains_fraud_proof::verification::verify_invalid_domain_extrinsics_root_fraud_proof;
use sp_domains_fraud_proof::{
FraudProofVerificationInfoRequest, FraudProofVerificationInfoResponse,
};
use sp_runtime::traits::{BlakeTwo256, CheckedSub, Hash, One, Zero};
use sp_runtime::{RuntimeAppPublic, SaturatedConversion, Saturating};
use sp_std::boxed::Box;
Expand Down Expand Up @@ -585,8 +588,12 @@ mod pallet {
InvalidTotalRewardsFraudProof(sp_domains::verification::VerificationError),
/// Invalid domain extrinsic fraud proof
InvalidExtrinsicRootFraudProof(sp_domains::verification::VerificationError),
/// Failed to get invalid domain extrinsic verification info.
FailedToGetInvalidDomainExtrinsicRootVerificationInfo,
/// Failed to get block randomness.
FailedToGetBlockRandomness,
/// Failed to get domain timestamp extrinsic.
FailedToGetDomainTimestampExtrinsic,
/// Received invalid Verification info from host function.
ReceivedInvalidVerificationInfo,
}

impl<T> From<FraudProofError> for Error<T> {
Expand Down Expand Up @@ -1491,11 +1498,29 @@ impl<T: Config> Pallet<T> {
}
FraudProof::InvalidExtrinsicsRoot(proof) => {
let consensus_block_hash = bad_receipt.consensus_block_hash;
let verification_info = get_invalid_domain_extrinsic_root_info(
let block_randomness = match get_fraud_proof_verification_info(
H256::from_slice(consensus_block_hash.as_ref()),
FraudProofVerificationInfoRequest::BlockRandomness,
)
.ok_or(FraudProofError::FailedToGetBlockRandomness)?
{
FraudProofVerificationInfoResponse::BlockRandomness(randomness) => {
Ok(randomness)
}
_ => Err(FraudProofError::ReceivedInvalidVerificationInfo),
}?;

let domain_timestamp_extrinsic = match get_fraud_proof_verification_info(
H256::from_slice(consensus_block_hash.as_ref()),
proof.domain_id,
FraudProofVerificationInfoRequest::DomainTimestampExtrinsic(proof.domain_id),
)
.ok_or(FraudProofError::FailedToGetInvalidDomainExtrinsicRootVerificationInfo)?;
.ok_or(FraudProofError::FailedToGetDomainTimestampExtrinsic)?
{
FraudProofVerificationInfoResponse::DomainTimestampExtrinsic(
domain_timestamp_extrinsic,
) => Ok(domain_timestamp_extrinsic),
_ => Err(FraudProofError::ReceivedInvalidVerificationInfo),
}?;

verify_invalid_domain_extrinsics_root_fraud_proof::<
T::Block,
Expand All @@ -1504,7 +1529,12 @@ impl<T: Config> Pallet<T> {
BalanceOf<T>,
T::Hashing,
T::DomainHashing,
>(bad_receipt, proof, verification_info)
>(
bad_receipt,
proof,
block_randomness,
domain_timestamp_extrinsic,
)
.map_err(FraudProofError::InvalidExtrinsicRootFraudProof)?;
}
_ => {}
Expand Down
47 changes: 31 additions & 16 deletions crates/pallet-domains/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ use sp_domains::{
StakingHoldIdentifier,
};
use sp_domains_fraud_proof::{
FraudProofExtension, FraudProofHostFunctions, InvalidDomainExtrinsicRootInfo,
FraudProofExtension, FraudProofHostFunctions, FraudProofVerificationInfoRequest,
FraudProofVerificationInfoResponse,
};
use sp_runtime::traits::{AccountIdConversion, BlakeTwo256, Hash as HashT, IdentityLookup, Zero};
use sp_runtime::{BuildStorage, OpaqueExtrinsic};
Expand Down Expand Up @@ -240,21 +241,35 @@ pub(crate) fn new_test_ext() -> sp_io::TestExternalities {
t.into()
}

pub(crate) struct MockDomainFraudProofExtension(Randomness, Moment);
pub(crate) struct MockDomainFraudProofExtension {
block_randomness: Randomness,
timestamp: Moment,
}

impl FraudProofHostFunctions for MockDomainFraudProofExtension {
fn get_invalid_domain_extrinsic_root_info(
fn get_fraud_proof_verification_info(
&self,
_consensus_block_hash: H256,
_domain_id: DomainId,
) -> Option<InvalidDomainExtrinsicRootInfo> {
Some(InvalidDomainExtrinsicRootInfo {
block_randomness: self.0,
timestamp_extrinsic: UncheckedExtrinsic::new_unsigned(
pallet_timestamp::Call::<Test>::set { now: self.1 }.into(),
)
.encode(),
})
fraud_proof_verification_info_req: FraudProofVerificationInfoRequest,
) -> Option<FraudProofVerificationInfoResponse> {
let response = match fraud_proof_verification_info_req {
FraudProofVerificationInfoRequest::BlockRandomness => {
FraudProofVerificationInfoResponse::BlockRandomness(self.block_randomness)
}
FraudProofVerificationInfoRequest::DomainTimestampExtrinsic(_) => {
FraudProofVerificationInfoResponse::DomainTimestampExtrinsic(
UncheckedExtrinsic::new_unsigned(
pallet_timestamp::Call::<Test>::set {
now: self.timestamp,
}
.into(),
)
.encode(),
)
}
};

Some(response)
}
}

Expand Down Expand Up @@ -883,10 +898,10 @@ fn test_invalid_domain_extrinsic_root_proof() {
fraud_proof
});

let fraud_proof_ext = FraudProofExtension::new(Arc::new(MockDomainFraudProofExtension(
Randomness::from([1u8; 32]),
1000,
)));
let fraud_proof_ext = FraudProofExtension::new(Arc::new(MockDomainFraudProofExtension {
block_randomness: Randomness::from([1u8; 32]),
timestamp: 1000,
}));
ext.register_extension(fraud_proof_ext);

ext.execute_with(|| {
Expand Down
85 changes: 59 additions & 26 deletions crates/sp-domains-fraud-proof/src/host_functions.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::InvalidDomainExtrinsicRootInfo;
use crate::{FraudProofVerificationInfoRequest, FraudProofVerificationInfoResponse};
use codec::Encode;
use domain_block_preprocessor::runtime_api::InherentExtrinsicConstructor;
use domain_block_preprocessor::runtime_api_light::RuntimeApiLight;
Expand All @@ -10,15 +10,16 @@ use sp_domains::{DomainId, DomainsApi};
use sp_runtime::traits::NumberFor;
use std::marker::PhantomData;
use std::sync::Arc;
use subspace_core_primitives::Randomness;

/// Trait to query and verify Domains Fraud proof.
pub trait FraudProofHostFunctions: Send + Sync {
/// Returns the required info to verify invalid domain extrinsic root.
fn get_invalid_domain_extrinsic_root_info(
/// Returns the required verification info for the runtime to verify the Fraud proof.
fn get_fraud_proof_verification_info(
&self,
consensus_block_hash: H256,
domain_id: DomainId,
) -> Option<InvalidDomainExtrinsicRootInfo>;
fraud_proof_verification_req: FraudProofVerificationInfoRequest,
) -> Option<FraudProofVerificationInfoResponse>;
}

sp_externalities::decl_extension! {
Expand Down Expand Up @@ -52,8 +53,8 @@ impl<Block, Client, DomainBlock, Executor>
}
}

impl<Block, Client, DomainBlock, Executor> FraudProofHostFunctions
for FraudProofHostFunctionsImpl<Block, Client, DomainBlock, Executor>
impl<Block, Client, DomainBlock, Executor>
FraudProofHostFunctionsImpl<Block, Client, DomainBlock, Executor>
where
Block: BlockT,
Block::Hash: From<H256>,
Expand All @@ -62,37 +63,69 @@ where
Client::Api: DomainsApi<Block, NumberFor<DomainBlock>, DomainBlock::Hash>,
Executor: CodeExecutor,
{
fn get_invalid_domain_extrinsic_root_info(
fn get_block_randomness(&self, consensus_block_hash: H256) -> Option<Randomness> {
let runtime_api = self.consensus_client.runtime_api();
let consensus_block_hash = consensus_block_hash.into();
runtime_api
.extrinsics_shuffling_seed(consensus_block_hash)
.ok()
}

fn derive_domain_timestamp_extrinsic(
&self,
consensus_block_hash: H256,
domain_id: DomainId,
) -> Option<InvalidDomainExtrinsicRootInfo> {
) -> 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 block_randomness = runtime_api
.extrinsics_shuffling_seed(consensus_block_hash)
.ok()?;
let timestamp = runtime_api.timestamp(consensus_block_hash).ok()?;

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

let timestamp_extrinsic =
InherentExtrinsicConstructor::<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(InvalidDomainExtrinsicRootInfo {
block_randomness,
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()
.map(|ext| ext.encode())
}
}

impl<Block, Client, DomainBlock, Executor> FraudProofHostFunctions
for FraudProofHostFunctionsImpl<Block, Client, DomainBlock, Executor>
where
Block: BlockT,
Block::Hash: From<H256>,
DomainBlock: BlockT,
Client: HeaderBackend<Block> + ProvideRuntimeApi<Block>,
Client::Api: DomainsApi<Block, NumberFor<DomainBlock>, DomainBlock::Hash>,
Executor: CodeExecutor,
{
fn get_fraud_proof_verification_info(
&self,
consensus_block_hash: H256,
fraud_proof_verification_req: FraudProofVerificationInfoRequest,
) -> Option<FraudProofVerificationInfoResponse> {
match fraud_proof_verification_req {
FraudProofVerificationInfoRequest::BlockRandomness => self
.get_block_randomness(consensus_block_hash)
.map(|block_randomness| {
FraudProofVerificationInfoResponse::BlockRandomness(block_randomness)
}),
FraudProofVerificationInfoRequest::DomainTimestampExtrinsic(doman_id) => self
.derive_domain_timestamp_extrinsic(consensus_block_hash, doman_id)
.map(|domain_timestamp_extrinsic| {
FraudProofVerificationInfoResponse::DomainTimestampExtrinsic(
domain_timestamp_extrinsic,
)
}),
}
}
}
26 changes: 22 additions & 4 deletions crates/sp-domains-fraud-proof/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,30 @@ pub use runtime_interface::fraud_proof_runtime_interface;
#[cfg(feature = "std")]
pub use runtime_interface::fraud_proof_runtime_interface::HostFunctions;
use sp_api::scale_info::TypeInfo;
use sp_domains::DomainId;
use sp_runtime_interface::pass_by;
use sp_runtime_interface::pass_by::PassBy;
use sp_std::vec::Vec;
use subspace_core_primitives::Randomness;

/// Type to hold required information to verify invalid domain extrinsics root.
/// Request type to fetch required verification information for fraud proof through Host function.
#[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone)]
pub struct InvalidDomainExtrinsicRootInfo {
pub block_randomness: Randomness,
pub timestamp_extrinsic: Vec<u8>,
pub enum FraudProofVerificationInfoRequest {
/// Block randomness at a given consensus block hash.
BlockRandomness,
/// Domain timestamp extrinsic using the timestamp at a given consensus block hash.
DomainTimestampExtrinsic(DomainId),
}

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

/// Response holds required verification information for fraud proof from Host function.
#[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone)]
pub enum FraudProofVerificationInfoResponse {
/// Block randomness fetched from consensus state at a specific block hash.
BlockRandomness(Randomness),
/// Encoded domain timestamp extrinsic using the timestamp from consensus state at a specific block hash.
DomainTimestampExtrinsic(Vec<u8>),
}
12 changes: 6 additions & 6 deletions crates/sp-domains-fraud-proof/src/runtime_interface.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
#[cfg(feature = "std")]
use crate::FraudProofExtension;
use crate::InvalidDomainExtrinsicRootInfo;
use crate::{FraudProofVerificationInfoRequest, FraudProofVerificationInfoResponse};
use sp_core::H256;
use sp_domains::DomainId;
#[cfg(feature = "std")]
use sp_externalities::ExternalitiesExt;
use sp_runtime_interface::runtime_interface;

/// Domain fraud proof related runtime interface
#[runtime_interface]
pub trait FraudProofRuntimeInterface {
fn get_invalid_domain_extrinsic_root_info(
/// Returns required fraud proof verification information to the runtime through host function.
fn get_fraud_proof_verification_info(
&mut self,
consensus_block_hash: H256,
domain_id: DomainId,
) -> Option<InvalidDomainExtrinsicRootInfo> {
fraud_proof_verification_req: FraudProofVerificationInfoRequest,
) -> Option<FraudProofVerificationInfoResponse> {
self.extension::<FraudProofExtension>()
.expect("No `FraudProofExtension` associated for the current context!")
.get_invalid_domain_extrinsic_root_info(consensus_block_hash, domain_id)
.get_fraud_proof_verification_info(consensus_block_hash, fraud_proof_verification_req)
}
}
12 changes: 4 additions & 8 deletions crates/sp-domains-fraud-proof/src/verification.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use crate::InvalidDomainExtrinsicRootInfo;
use hash_db::Hasher;
use sp_core::H256;
use sp_domains::fraud_proof::{ExtrinsicDigest, InvalidExtrinsicsRootProof};
Expand Down Expand Up @@ -29,7 +28,8 @@ pub fn verify_invalid_domain_extrinsics_root_fraud_proof<
Balance,
>,
fraud_proof: &InvalidExtrinsicsRootProof,
verification_info: InvalidDomainExtrinsicRootInfo,
block_randomness: Randomness,
domain_timestamp_extrinsic: Vec<u8>,
) -> Result<(), VerificationError>
where
CBlock: Block,
Expand All @@ -42,11 +42,6 @@ where
..
} = fraud_proof;

let InvalidDomainExtrinsicRootInfo {
block_randomness,
timestamp_extrinsic,
} = verification_info;

let mut bundle_extrinsics_digests = Vec::new();
for (bad_receipt_valid_bundle_digest, bundle_digest) in bad_receipt
.valid_bundle_digests()
Expand All @@ -69,7 +64,8 @@ where
Randomness::from(shuffling_seed.to_fixed_bytes()),
);

let timestamp_extrinsic = ExtrinsicDigest::new::<LayoutV1<DomainHashing>>(timestamp_extrinsic);
let timestamp_extrinsic =
ExtrinsicDigest::new::<LayoutV1<DomainHashing>>(domain_timestamp_extrinsic);
ordered_extrinsics.insert(0, timestamp_extrinsic);

let ordered_trie_node_values = ordered_extrinsics
Expand Down

0 comments on commit 8a20edc

Please sign in to comment.