sp_domains/execution_receipt/
execution_receipt_v0.rs

1#[cfg(not(feature = "std"))]
2extern crate alloc;
3
4use crate::bundle::{BundleValidity, InboxedBundle};
5use crate::execution_receipt::{BlockFees, Transfers};
6use crate::{HeaderHashFor, HeaderHashingFor, HeaderNumberFor, OperatorSignature, ProofOfElection};
7#[cfg(not(feature = "std"))]
8use alloc::collections::BTreeSet;
9#[cfg(not(feature = "std"))]
10use alloc::string::String;
11#[cfg(not(feature = "std"))]
12use alloc::vec::Vec;
13use parity_scale_codec::{Decode, Encode};
14use scale_info::TypeInfo;
15use sp_core::H256;
16use sp_runtime::traits::{Hash as HashT, Header as HeaderT, NumberFor};
17use subspace_runtime_primitives::BlockHashFor;
18
19/// Receipt V0 of a domain block execution.
20#[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone)]
21pub struct ExecutionReceiptV0<Number, Hash, DomainNumber, DomainHash, Balance> {
22    /// The index of the current domain block that forms the basis of this ER.
23    pub domain_block_number: DomainNumber,
24    /// The block hash corresponding to `domain_block_number`.
25    pub domain_block_hash: DomainHash,
26    /// Extrinsic root field of the header of domain block referenced by this ER.
27    pub domain_block_extrinsic_root: DomainHash,
28    /// The hash of the ER for the last domain block.
29    pub parent_domain_block_receipt_hash: DomainHash,
30    /// A pointer to the consensus block index which contains all of the bundles that were used to derive and
31    /// order all extrinsics executed by the current domain block for this ER.
32    pub consensus_block_number: Number,
33    /// The block hash corresponding to `consensus_block_number`.
34    pub consensus_block_hash: Hash,
35    /// All the bundles that being included in the consensus block.
36    pub inboxed_bundles: Vec<InboxedBundle<DomainHash>>,
37    /// The final state root for the current domain block reflected by this ER.
38    ///
39    /// Used for verifying storage proofs for domains.
40    pub final_state_root: DomainHash,
41    /// List of storage roots collected during the domain block execution.
42    pub execution_trace: Vec<DomainHash>,
43    /// The Merkle root of the execution trace for the current domain block.
44    ///
45    /// Used for verifying fraud proofs.
46    pub execution_trace_root: H256,
47    /// Compute and Domain storage fees are shared across operators and Consensus
48    /// storage fees are given to the consensus block author.
49    pub block_fees: BlockFees<Balance>,
50    /// List of transfers from this Domain to other chains
51    pub transfers: Transfers<Balance>,
52}
53
54impl<Number, Hash, DomainNumber, DomainHash, Balance>
55    ExecutionReceiptV0<Number, Hash, DomainNumber, DomainHash, Balance>
56{
57    pub fn bundles_extrinsics_roots(&self) -> Vec<&DomainHash> {
58        self.inboxed_bundles
59            .iter()
60            .map(|b| &b.extrinsics_root)
61            .collect()
62    }
63
64    pub fn valid_bundle_digest_at(&self, index: usize) -> Option<DomainHash>
65    where
66        DomainHash: Copy,
67    {
68        match self.inboxed_bundles.get(index).map(|ib| &ib.bundle) {
69            Some(BundleValidity::Valid(bundle_digest_hash)) => Some(*bundle_digest_hash),
70            _ => None,
71        }
72    }
73
74    pub fn valid_bundle_digests(&self) -> Vec<DomainHash>
75    where
76        DomainHash: Copy,
77    {
78        self.inboxed_bundles
79            .iter()
80            .filter_map(|b| match b.bundle {
81                BundleValidity::Valid(bundle_digest_hash) => Some(bundle_digest_hash),
82                BundleValidity::Invalid(_) => None,
83            })
84            .collect()
85    }
86
87    pub fn valid_bundle_indexes(&self) -> Vec<u32> {
88        self.inboxed_bundles
89            .iter()
90            .enumerate()
91            .filter_map(|(index, b)| match b.bundle {
92                BundleValidity::Valid(_) => Some(index as u32),
93                BundleValidity::Invalid(_) => None,
94            })
95            .collect()
96    }
97}
98
99impl<Number, Hash, DomainNumber, DomainHash, Balance>
100    ExecutionReceiptV0<Number, Hash, DomainNumber, DomainHash, Balance>
101where
102    Number: Encode,
103    Hash: Encode,
104    DomainNumber: Encode,
105    DomainHash: Encode,
106    Balance: Encode,
107{
108    pub fn hash<DomainHashing: HashT<Output = DomainHash>>(&self) -> DomainHash {
109        DomainHashing::hash_of(self)
110    }
111}
112
113/// Singleton receipt submit along when there is a gap between `domain_best_number`
114/// and `HeadReceiptNumber`
115#[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone)]
116pub struct SingletonReceiptV0<Number, Hash, DomainHeader: HeaderT, Balance> {
117    /// Proof of receipt producer election.
118    pub proof_of_election: ProofOfElection,
119    /// The receipt to submit
120    pub receipt: ExecutionReceiptV0<
121        Number,
122        Hash,
123        HeaderNumberFor<DomainHeader>,
124        HeaderHashFor<DomainHeader>,
125        Balance,
126    >,
127}
128
129impl<Number: Encode, Hash: Encode, DomainHeader: HeaderT, Balance: Encode>
130    SingletonReceiptV0<Number, Hash, DomainHeader, Balance>
131{
132    pub fn hash(&self) -> HeaderHashFor<DomainHeader> {
133        HeaderHashingFor::<DomainHeader>::hash_of(&self)
134    }
135}
136
137#[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone)]
138pub struct SealedSingletonReceiptV0<Number, Hash, DomainHeader: HeaderT, Balance> {
139    /// A collection of the receipt.
140    pub singleton_receipt: SingletonReceiptV0<Number, Hash, DomainHeader, Balance>,
141    /// Signature of the receipt bundle.
142    pub signature: OperatorSignature,
143}
144
145pub type ExecutionReceiptV0For<DomainHeader, CBlock, Balance> = ExecutionReceiptV0<
146    NumberFor<CBlock>,
147    BlockHashFor<CBlock>,
148    <DomainHeader as HeaderT>::Number,
149    <DomainHeader as HeaderT>::Hash,
150    Balance,
151>;