Skip to content

Commit 18be01e

Browse files
authored
Merge pull request #1026 from subspace/fraud-proof-submit
Submit core domain fraud proof to the system domain through the ParentChainInterface trait
2 parents 23cea50 + c4033ab commit 18be01e

File tree

13 files changed

+219
-105
lines changed

13 files changed

+219
-105
lines changed

domains/client/domain-executor/src/core_bundle_processor.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::domain_block_processor::DomainBlockProcessor;
2+
use crate::parent_chain::{CoreDomainParentChain, ParentChainInterface};
23
use crate::utils::{translate_number_type, DomainBundles};
34
use crate::TransactionFor;
45
use domain_runtime_primitives::{AccountId, DomainCoreApi};
@@ -29,6 +30,7 @@ where
2930
domain_id: DomainId,
3031
primary_chain_client: Arc<PClient>,
3132
system_domain_client: Arc<SClient>,
33+
parent_chain: CoreDomainParentChain<SClient, SBlock, PBlock>,
3234
client: Arc<Client>,
3335
backend: Arc<Backend>,
3436
keystore: SyncCryptoStorePtr,
@@ -48,6 +50,7 @@ where
4850
domain_id: self.domain_id,
4951
primary_chain_client: self.primary_chain_client.clone(),
5052
system_domain_client: self.system_domain_client.clone(),
53+
parent_chain: self.parent_chain.clone(),
5154
client: self.client.clone(),
5255
backend: self.backend.clone(),
5356
keystore: self.keystore.clone(),
@@ -91,10 +94,15 @@ where
9194
keystore: SyncCryptoStorePtr,
9295
domain_block_processor: DomainBlockProcessor<Block, PBlock, Client, PClient, Backend, E>,
9396
) -> Self {
97+
let parent_chain = CoreDomainParentChain::<SClient, SBlock, PBlock>::new(
98+
system_domain_client.clone(),
99+
domain_id,
100+
);
94101
Self {
95102
domain_id,
96103
primary_chain_client,
97104
system_domain_client,
105+
parent_chain,
98106
client,
99107
backend,
100108
keystore,
@@ -175,13 +183,7 @@ where
175183
head_receipt_number,
176184
oldest_receipt_number,
177185
)? {
178-
// TODO: self.system_domain_client.runtime_api().submit_fraud_proof_unsigned()
179-
self.primary_chain_client
180-
.runtime_api()
181-
.submit_fraud_proof_unsigned(
182-
&BlockId::Hash(self.primary_chain_client.info().best_hash),
183-
fraud_proof,
184-
)?;
186+
self.parent_chain.submit_fraud_proof_unsigned(fraud_proof)?;
185187
}
186188

187189
Ok(())

domains/client/domain-executor/src/core_bundle_producer.rs

Lines changed: 12 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::bundle_election_solver::BundleElectionSolver;
2-
use crate::domain_bundle_producer::{sign_new_bundle, ReceiptInterface};
2+
use crate::domain_bundle_producer::sign_new_bundle;
33
use crate::domain_bundle_proposer::DomainBundleProposer;
4+
use crate::parent_chain::CoreDomainParentChain;
45
use crate::utils::{to_number_primitive, ExecutorSlotInfo};
56
use crate::BundleSender;
67
use codec::{Decode, Encode};
@@ -15,7 +16,6 @@ use sp_runtime::generic::BlockId;
1516
use sp_runtime::traits::{Block as BlockT, Header as HeaderT};
1617
use std::marker::PhantomData;
1718
use std::sync::Arc;
18-
use subspace_core_primitives::BlockNumber;
1919
use system_runtime_primitives::SystemDomainApi;
2020

2121
pub(super) struct CoreBundleProducer<Block, SBlock, PBlock, Client, SClient, TransactionPool>
@@ -27,6 +27,7 @@ where
2727
domain_id: DomainId,
2828
system_domain_client: Arc<SClient>,
2929
client: Arc<Client>,
30+
parent_chain: CoreDomainParentChain<SClient, SBlock, PBlock>,
3031
bundle_sender: Arc<BundleSender<Block, PBlock>>,
3132
is_authority: bool,
3233
keystore: SyncCryptoStorePtr,
@@ -47,6 +48,7 @@ where
4748
domain_id: self.domain_id,
4849
system_domain_client: self.system_domain_client.clone(),
4950
client: self.client.clone(),
51+
parent_chain: self.parent_chain.clone(),
5052
bundle_sender: self.bundle_sender.clone(),
5153
is_authority: self.is_authority,
5254
keystore: self.keystore.clone(),
@@ -57,32 +59,6 @@ where
5759
}
5860
}
5961

60-
impl<Block, SBlock, PBlock, Client, SClient, TransactionPool> ReceiptInterface<SBlock::Hash>
61-
for CoreBundleProducer<Block, SBlock, PBlock, Client, SClient, TransactionPool>
62-
where
63-
Block: BlockT,
64-
SBlock: BlockT,
65-
PBlock: BlockT,
66-
SClient: ProvideRuntimeApi<SBlock>,
67-
SClient::Api: SystemDomainApi<SBlock, NumberFor<PBlock>, PBlock::Hash>,
68-
{
69-
fn head_receipt_number(&self, at: SBlock::Hash) -> Result<BlockNumber, sp_api::ApiError> {
70-
let head_receipt_number = self
71-
.system_domain_client
72-
.runtime_api()
73-
.head_receipt_number(&BlockId::Hash(at), self.domain_id)?;
74-
Ok(to_number_primitive(head_receipt_number))
75-
}
76-
77-
fn maximum_receipt_drift(&self, at: SBlock::Hash) -> Result<BlockNumber, sp_api::ApiError> {
78-
let max_drift = self
79-
.system_domain_client
80-
.runtime_api()
81-
.maximum_receipt_drift(&BlockId::Hash(at))?;
82-
Ok(to_number_primitive(max_drift))
83-
}
84-
}
85-
8662
impl<Block, SBlock, PBlock, Client, SClient, TransactionPool>
8763
CoreBundleProducer<Block, SBlock, PBlock, Client, SClient, TransactionPool>
8864
where
@@ -110,10 +86,15 @@ where
11086
keystore.clone(),
11187
);
11288
let domain_bundle_proposer = DomainBundleProposer::new(client.clone(), transaction_pool);
89+
let parent_chain = CoreDomainParentChain::<SClient, SBlock, PBlock>::new(
90+
system_domain_client.clone(),
91+
domain_id,
92+
);
11393
Self {
11494
domain_id,
11595
system_domain_client,
11696
client,
97+
parent_chain,
11798
bundle_sender,
11899
is_authority,
119100
keystore,
@@ -123,18 +104,14 @@ where
123104
}
124105
}
125106

126-
pub(super) async fn produce_bundle<R>(
107+
pub(super) async fn produce_bundle(
127108
self,
128109
primary_info: (PBlock::Hash, NumberFor<PBlock>),
129110
slot_info: ExecutorSlotInfo,
130-
receipt_interface: R,
131111
) -> Result<
132112
Option<SignedOpaqueBundle<NumberFor<PBlock>, PBlock::Hash, Block::Hash>>,
133113
sp_blockchain::Error,
134-
>
135-
where
136-
R: ReceiptInterface<SBlock::Hash>,
137-
{
114+
> {
138115
if !self.is_authority {
139116
return Ok(None);
140117
}
@@ -160,7 +137,7 @@ where
160137

161138
let bundle = self
162139
.domain_bundle_proposer
163-
.propose_bundle_at::<PBlock, _, _>(slot, primary_info, receipt_interface, best_hash)
140+
.propose_bundle_at::<PBlock, _, _>(slot, primary_info, self.parent_chain, best_hash)
164141
.await?;
165142

166143
let core_block_number = to_number_primitive(self.client.info().best_number);

domains/client/domain-executor/src/core_domain_worker.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,10 +133,9 @@ pub(super) async fn start_worker<
133133
let handle_slot_notifications_fut = handle_slot_notifications::<Block, PBlock, _, _>(
134134
primary_chain_client.as_ref(),
135135
move |primary_info, slot_info| {
136-
let receipt_interface = bundle_producer.clone();
137136
bundle_producer
138137
.clone()
139-
.produce_bundle(primary_info, slot_info, receipt_interface)
138+
.produce_bundle(primary_info, slot_info)
140139
.instrument(span.clone())
141140
.unwrap_or_else(move |error| {
142141
tracing::error!(?primary_info, ?error, "Error at producing bundle.");

domains/client/domain-executor/src/domain_bundle_producer.rs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,6 @@ use sp_domains::{Bundle, BundleSolution, ExecutorPublicKey, ExecutorSignature, S
33
use sp_keystore::{SyncCryptoStore, SyncCryptoStorePtr};
44
use sp_runtime::traits::{Block as BlockT, NumberFor};
55
use sp_runtime::RuntimeAppPublic;
6-
use subspace_core_primitives::BlockNumber;
7-
8-
// TODO: this may be extended into ParentChainInterface due to the relative relation between the
9-
// chains regarding the settlement aspect.
10-
// - Primary Chain => System Domain
11-
// - System Domain => Core Domain
12-
/// Trait for retrieving the necessary info for collecting the receipts in a new domain bundle.
13-
pub(crate) trait ReceiptInterface<Hash> {
14-
fn head_receipt_number(&self, at: Hash) -> Result<BlockNumber, sp_api::ApiError>;
15-
fn maximum_receipt_drift(&self, at: Hash) -> Result<BlockNumber, sp_api::ApiError>;
16-
}
176

187
type SignedOpaqueBundle<Block, PBlock> = sp_domains::SignedOpaqueBundle<
198
NumberFor<PBlock>,

domains/client/domain-executor/src/domain_bundle_proposer.rs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::domain_bundle_producer::ReceiptInterface;
1+
use crate::parent_chain::ParentChainInterface;
22
use crate::utils::to_number_primitive;
33
use crate::ExecutionReceiptFor;
44
use codec::Encode;
@@ -52,12 +52,12 @@ where
5252
&self,
5353
slot: Slot,
5454
primary_info: (PBlock::Hash, NumberFor<PBlock>),
55-
receipt_interface: R,
56-
receipt_interface_block_hash: RHash,
55+
parent_chain: R,
56+
parent_chain_block_hash: RHash,
5757
) -> sp_blockchain::Result<Bundle<Block::Extrinsic, NumberFor<PBlock>, PBlock::Hash, Block::Hash>>
5858
where
5959
PBlock: BlockT,
60-
R: ReceiptInterface<RHash>,
60+
R: ParentChainInterface<RHash>,
6161
RHash: Copy,
6262
{
6363
let parent_number = self.client.info().best_number;
@@ -109,8 +109,8 @@ where
109109
} else {
110110
self.collect_bundle_receipts::<PBlock, _, _>(
111111
parent_number,
112-
receipt_interface,
113-
receipt_interface_block_hash,
112+
parent_chain,
113+
parent_chain_block_hash,
114114
)?
115115
};
116116

@@ -131,17 +131,16 @@ where
131131
fn collect_bundle_receipts<PBlock, R, RHash>(
132132
&self,
133133
header_number: NumberFor<Block>,
134-
receipt_interface: R,
135-
receipt_interface_block_hash: RHash,
134+
parent_chain: R,
135+
parent_chain_block_hash: RHash,
136136
) -> sp_blockchain::Result<Vec<ExecutionReceiptFor<PBlock, Block::Hash>>>
137137
where
138138
PBlock: BlockT,
139-
R: ReceiptInterface<RHash>,
139+
R: ParentChainInterface<RHash>,
140140
RHash: Copy,
141141
{
142-
let head_receipt_number =
143-
receipt_interface.head_receipt_number(receipt_interface_block_hash)?;
144-
let max_drift = receipt_interface.maximum_receipt_drift(receipt_interface_block_hash)?;
142+
let head_receipt_number = parent_chain.head_receipt_number(parent_chain_block_hash)?;
143+
let max_drift = parent_chain.maximum_receipt_drift(parent_chain_block_hash)?;
145144

146145
let load_receipt = |block_hash| {
147146
crate::aux_schema::load_execution_receipt::<

domains/client/domain-executor/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ mod domain_worker;
7474
mod fraud_proof;
7575
mod gossip_message_validator;
7676
mod merkle_tree;
77+
mod parent_chain;
7778
mod system_bundle_processor;
7879
mod system_bundle_producer;
7980
mod system_domain_worker;
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
use crate::utils::to_number_primitive;
2+
use sp_api::{NumberFor, ProvideRuntimeApi};
3+
use sp_blockchain::HeaderBackend;
4+
use sp_domains::fraud_proof::FraudProof;
5+
use sp_domains::{DomainId, ExecutorApi};
6+
use sp_runtime::generic::BlockId;
7+
use sp_runtime::traits::Block as BlockT;
8+
use std::marker::PhantomData;
9+
use std::sync::Arc;
10+
use subspace_core_primitives::BlockNumber;
11+
use system_runtime_primitives::SystemDomainApi;
12+
13+
/// Trait for interacting between the domain and its corresponding parent chain, i.e. retrieving
14+
/// the necessary info from the parent chain or submit extrinsics to the parent chain.
15+
///
16+
/// - The parent chain of System Domain => Primary Chain
17+
/// - The parent chain of Core Domain => System Domain
18+
pub(crate) trait ParentChainInterface<Hash> {
19+
fn head_receipt_number(&self, at: Hash) -> Result<BlockNumber, sp_api::ApiError>;
20+
fn maximum_receipt_drift(&self, at: Hash) -> Result<BlockNumber, sp_api::ApiError>;
21+
fn submit_fraud_proof_unsigned(&self, fraud_proof: FraudProof) -> Result<(), sp_api::ApiError>;
22+
}
23+
24+
/// The parent chain of the core domain
25+
pub struct CoreDomainParentChain<SClient, SBlock, PBlock> {
26+
system_domain_client: Arc<SClient>,
27+
// Core domain id
28+
domain_id: DomainId,
29+
_phantom: PhantomData<(SBlock, PBlock)>,
30+
}
31+
32+
impl<SClient, SBlock, PBlock> Clone for CoreDomainParentChain<SClient, SBlock, PBlock> {
33+
fn clone(&self) -> Self {
34+
CoreDomainParentChain {
35+
system_domain_client: self.system_domain_client.clone(),
36+
domain_id: self.domain_id,
37+
_phantom: self._phantom,
38+
}
39+
}
40+
}
41+
42+
impl<SBlock, PBlock, SClient> CoreDomainParentChain<SClient, SBlock, PBlock> {
43+
pub fn new(system_domain_client: Arc<SClient>, domain_id: DomainId) -> Self {
44+
CoreDomainParentChain {
45+
system_domain_client,
46+
domain_id,
47+
_phantom: PhantomData::default(),
48+
}
49+
}
50+
}
51+
52+
impl<SBlock, PBlock, SClient> ParentChainInterface<SBlock::Hash>
53+
for CoreDomainParentChain<SClient, SBlock, PBlock>
54+
where
55+
SBlock: BlockT,
56+
PBlock: BlockT,
57+
SClient: HeaderBackend<SBlock> + ProvideRuntimeApi<SBlock>,
58+
SClient::Api: SystemDomainApi<SBlock, NumberFor<PBlock>, PBlock::Hash>,
59+
{
60+
fn head_receipt_number(&self, at: SBlock::Hash) -> Result<BlockNumber, sp_api::ApiError> {
61+
let head_receipt_number = self
62+
.system_domain_client
63+
.runtime_api()
64+
.head_receipt_number(&BlockId::Hash(at), self.domain_id)?;
65+
Ok(to_number_primitive(head_receipt_number))
66+
}
67+
68+
fn maximum_receipt_drift(&self, at: SBlock::Hash) -> Result<BlockNumber, sp_api::ApiError> {
69+
let max_drift = self
70+
.system_domain_client
71+
.runtime_api()
72+
.maximum_receipt_drift(&BlockId::Hash(at))?;
73+
Ok(to_number_primitive(max_drift))
74+
}
75+
76+
fn submit_fraud_proof_unsigned(&self, fraud_proof: FraudProof) -> Result<(), sp_api::ApiError> {
77+
let at = self.system_domain_client.info().best_hash;
78+
self.system_domain_client
79+
.runtime_api()
80+
.submit_fraud_proof_unsigned(&BlockId::Hash(at), fraud_proof)?;
81+
Ok(())
82+
}
83+
}
84+
85+
/// The parent chain of the system domain
86+
pub struct SystemDomainParentChain<PClient, Block, PBlock> {
87+
primary_chain_client: Arc<PClient>,
88+
_phantom: PhantomData<(Block, PBlock)>,
89+
}
90+
91+
impl<PClient, Block, PBlock> Clone for SystemDomainParentChain<PClient, Block, PBlock> {
92+
fn clone(&self) -> Self {
93+
SystemDomainParentChain {
94+
primary_chain_client: self.primary_chain_client.clone(),
95+
_phantom: self._phantom,
96+
}
97+
}
98+
}
99+
100+
impl<PClient, Block, PBlock> SystemDomainParentChain<PClient, Block, PBlock> {
101+
pub fn new(primary_chain_client: Arc<PClient>) -> Self {
102+
SystemDomainParentChain {
103+
primary_chain_client,
104+
_phantom: PhantomData::default(),
105+
}
106+
}
107+
}
108+
109+
impl<Block, PBlock, PClient> ParentChainInterface<PBlock::Hash>
110+
for SystemDomainParentChain<PClient, Block, PBlock>
111+
where
112+
Block: BlockT,
113+
PBlock: BlockT,
114+
PClient: HeaderBackend<PBlock> + ProvideRuntimeApi<PBlock>,
115+
PClient::Api: ExecutorApi<PBlock, Block::Hash>,
116+
{
117+
fn head_receipt_number(&self, at: PBlock::Hash) -> Result<BlockNumber, sp_api::ApiError> {
118+
let head_receipt_number = self
119+
.primary_chain_client
120+
.runtime_api()
121+
.head_receipt_number(&BlockId::Hash(at))?;
122+
Ok(to_number_primitive(head_receipt_number))
123+
}
124+
125+
fn maximum_receipt_drift(&self, at: PBlock::Hash) -> Result<BlockNumber, sp_api::ApiError> {
126+
let max_drift = self
127+
.primary_chain_client
128+
.runtime_api()
129+
.maximum_receipt_drift(&BlockId::Hash(at))?;
130+
Ok(to_number_primitive(max_drift))
131+
}
132+
133+
fn submit_fraud_proof_unsigned(&self, fraud_proof: FraudProof) -> Result<(), sp_api::ApiError> {
134+
let at = self.primary_chain_client.info().best_hash;
135+
self.primary_chain_client
136+
.runtime_api()
137+
.submit_fraud_proof_unsigned(&BlockId::Hash(at), fraud_proof)?;
138+
Ok(())
139+
}
140+
}

0 commit comments

Comments
 (0)