sov_rollup_interface/node/services/
da.rs

1//! The da module defines traits used by the full node to interact with the DA layer.
2use std::fmt::{self, Display};
3
4use async_trait::async_trait;
5use serde::de::DeserializeOwned;
6use serde::Serialize;
7
8use crate::da::{BlockHeaderTrait, DaSpec, DaVerifier};
9use crate::zk::ValidityCondition;
10
11/// A DaService is the local side of an RPC connection talking to a node of the DA layer
12/// It is *not* part of the logic that is zk-proven.
13///
14/// The DaService has two responsibilities - fetching data from the DA layer, transforming the
15/// data into a representation that can be efficiently verified in circuit.
16#[async_trait]
17pub trait DaService: Send + Sync + 'static {
18    /// A handle to the types used by the DA layer.
19    type Spec: DaSpec;
20
21    /// The verifier for this DA layer.
22    type Verifier: DaVerifier<Spec = Self::Spec>;
23
24    /// A DA layer block, possibly excluding some irrelevant information.
25    type FilteredBlock: SlotData<
26        BlockHeader = <Self::Spec as DaSpec>::BlockHeader,
27        Cond = <Self::Spec as DaSpec>::ValidityCondition,
28    >;
29
30    /// The error type for fallible methods.
31    type Error: fmt::Debug + Send + Sync + Display;
32
33    /// Retrieve the data for the given height, waiting for it to be
34    /// finalized if necessary. The block, once returned, must not be reverted
35    /// without a consensus violation.
36    async fn get_finalized_at(&self, height: u64) -> Result<Self::FilteredBlock, Self::Error>;
37
38    /// Fetch the block at the given height, waiting for one to be mined if necessary.
39    /// The returned block may not be final, and can be reverted without a consensus violation
40    async fn get_block_at(&self, height: u64) -> Result<Self::FilteredBlock, Self::Error>;
41
42    /// Extract the relevant transactions from a block. For example, this method might return
43    /// all of the blob transactions in rollup's namespace on Celestia.
44    fn extract_relevant_blobs(
45        &self,
46        block: &Self::FilteredBlock,
47    ) -> Vec<<Self::Spec as DaSpec>::BlobTransaction>;
48
49    /// Generate a proof that the relevant blob transactions have been extracted correctly from the DA layer
50    /// block.
51    async fn get_extraction_proof(
52        &self,
53        block: &Self::FilteredBlock,
54        blobs: &[<Self::Spec as DaSpec>::BlobTransaction],
55    ) -> (
56        <Self::Spec as DaSpec>::InclusionMultiProof,
57        <Self::Spec as DaSpec>::CompletenessProof,
58    );
59
60    /// Extract the relevant transactions from a block, along with a proof that the extraction has been done correctly.
61    /// For example, this method might return all of the blob transactions in rollup's namespace on Celestia,
62    /// together with a range proof against the root of the namespaced-merkle-tree, demonstrating that the entire
63    /// rollup namespace has been covered.
64    #[allow(clippy::type_complexity)]
65    async fn extract_relevant_blobs_with_proof(
66        &self,
67        block: &Self::FilteredBlock,
68    ) -> (
69        Vec<<Self::Spec as DaSpec>::BlobTransaction>,
70        <Self::Spec as DaSpec>::InclusionMultiProof,
71        <Self::Spec as DaSpec>::CompletenessProof,
72    ) {
73        let relevant_txs = self.extract_relevant_blobs(block);
74
75        let (etx_proofs, rollup_row_proofs) = self
76            .get_extraction_proof(block, relevant_txs.as_slice())
77            .await;
78
79        (relevant_txs, etx_proofs, rollup_row_proofs)
80    }
81
82    /// Send a transaction directly to the DA layer.
83    /// blob is the serialized and signed transaction.
84    /// Returns nothing if the transaction was successfully sent.
85    async fn send_transaction(&self, blob: &[u8]) -> Result<(), Self::Error>;
86}
87
88/// `SlotData` is the subset of a DA layer block which is stored in the rollup's database.
89/// At the very least, the rollup needs access to the hashes and headers of all DA layer blocks, but rollups
90/// may choose to store partial (or full) block data as well.
91pub trait SlotData:
92    Serialize + DeserializeOwned + PartialEq + core::fmt::Debug + Clone + Send + Sync
93{
94    /// The header type for a DA layer block as viewed by the rollup. This need not be identical
95    /// to the underlying rollup's header type, but it must be sufficient to reconstruct the block hash.
96    ///
97    /// For example, most fields of the a Tendermint-based DA chain like Celestia are irrelevant to the rollup.
98    /// For these fields, we only ever store their *serialized* representation in memory or on disk. Only a few special
99    /// fields like `data_root` are stored in decoded form in the `CelestiaHeader` struct.
100    type BlockHeader: BlockHeaderTrait;
101
102    /// The validity condition associated with the slot data.
103    type Cond: ValidityCondition;
104
105    /// The canonical hash of the DA layer block.
106    fn hash(&self) -> [u8; 32];
107    /// The header of the DA layer block.
108    fn header(&self) -> &Self::BlockHeader;
109    /// Get the validity condition set associated with the slot
110    fn validity_condition(&self) -> Self::Cond;
111}