1
// Copyright (C) Moondance Labs Ltd.
2
// This file is part of Tanssi.
3

            
4
// Tanssi is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8

            
9
// Tanssi is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13

            
14
// You should have received a copy of the GNU General Public License
15
// along with Tanssi.  If not, see <http://www.gnu.org/licenses/>
16

            
17
use {
18
    crate::OwnParachainInherentData,
19
    cumulus_primitives_core::ParaId,
20
    cumulus_relay_chain_interface::{PHash, RelayChainInterface},
21
    dp_core::well_known_keys::para_id_head,
22
};
23

            
24
/// Collect the relevant relay chain state in form of a proof
25
/// for putting it into the author
26
/// noting inherent.
27
3
async fn collect_relay_storage_proof(
28
3
    relay_chain_interface: &impl RelayChainInterface,
29
3
    para_ids: &[ParaId],
30
3
    relay_parent: PHash,
31
3
) -> Option<sp_state_machine::StorageProof> {
32
3
    let relevant_keys = para_ids
33
3
        .iter()
34
3
        .map(|para_id| para_id_head(*para_id))
35
3
        .collect();
36
3

            
37
3
    relay_chain_interface
38
3
        .prove_read(relay_parent, &relevant_keys)
39
3
        .await
40
3
        .ok()
41
3
}
42

            
43
impl OwnParachainInherentData {
44
    /// Create the [`OwnParachainInherentData`] at the given `relay_parent`.
45
    ///
46
    /// Returns `None` if the creation failed.
47
3
    pub async fn create_at(
48
3
        relay_parent: PHash,
49
3
        relay_chain_interface: &impl RelayChainInterface,
50
3
        para_ids: &[ParaId],
51
3
    ) -> Option<OwnParachainInherentData> {
52
3
        let relay_storage_proof =
53
3
            collect_relay_storage_proof(relay_chain_interface, para_ids, relay_parent).await?;
54

            
55
3
        Some(OwnParachainInherentData {
56
3
            relay_storage_proof,
57
3
        })
58
3
    }
59
}
60

            
61
// Implementation of InherentDataProvider
62
#[async_trait::async_trait]
63
impl sp_inherents::InherentDataProvider for OwnParachainInherentData {
64
    async fn provide_inherent_data(
65
        &self,
66
        inherent_data: &mut sp_inherents::InherentData,
67
1
    ) -> Result<(), sp_inherents::Error> {
68
1
        inherent_data.put_data(crate::INHERENT_IDENTIFIER, &self)
69
2
    }
70

            
71
    async fn try_handle_error(
72
        &self,
73
        _: &sp_inherents::InherentIdentifier,
74
        _: &[u8],
75
    ) -> Option<Result<(), sp_inherents::Error>> {
76
        None
77
    }
78
}