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
    super::*,
19
    core::fmt::Debug,
20
    dp_core::ParaId,
21
    frame_support::{dispatch::DispatchErrorWithPostInfo, pallet_prelude::*},
22
    parity_scale_codec::FullCodec,
23
    serde::{de::DeserializeOwned, Deserialize, Serialize},
24
};
25

            
26
/// Data preserver profile.
27
#[derive(
28
    RuntimeDebugNoBound,
29
    PartialEqNoBound,
30
    EqNoBound,
31
    Encode,
32
    Decode,
33
    CloneNoBound,
34
880
    TypeInfo,
35
    Serialize,
36
    Deserialize,
37
)]
38
#[scale_info(skip_type_params(T))]
39
pub struct Profile<T: Config> {
40
    pub url: BoundedVec<u8, T::MaxNodeUrlLen>,
41
    pub para_ids: ParaIdsFilter<T>,
42
    pub mode: ProfileMode,
43
    pub assignment_request: ProviderRequestOf<T>,
44
}
45

            
46
#[derive(
47
    RuntimeDebugNoBound,
48
    PartialEqNoBound,
49
    EqNoBound,
50
    Encode,
51
    Decode,
52
    CloneNoBound,
53
1056
    TypeInfo,
54
    Serialize,
55
    Deserialize,
56
)]
57
#[scale_info(skip_type_params(T))]
58
pub enum ParaIdsFilter<T: Config> {
59
252
    AnyParaId,
60
86
    Whitelist(BoundedBTreeSet<ParaId, T::MaxParaIdsVecLen>),
61
    Blacklist(BoundedBTreeSet<ParaId, T::MaxParaIdsVecLen>),
62
}
63

            
64
impl<T: Config> ParaIdsFilter<T> {
65
    #[allow(clippy::len_without_is_empty)]
66
72
    pub fn len(&self) -> usize {
67
72
        match self {
68
24
            Self::AnyParaId => 0,
69
48
            Self::Whitelist(list) | Self::Blacklist(list) => list.len(),
70
        }
71
72
    }
72

            
73
97
    pub fn can_assign(&self, para_id: &ParaId) -> bool {
74
97
        match self {
75
81
            ParaIdsFilter::AnyParaId => true,
76
16
            ParaIdsFilter::Whitelist(list) => list.contains(para_id),
77
            ParaIdsFilter::Blacklist(list) => !list.contains(para_id),
78
        }
79
97
    }
80
}
81

            
82
704
#[derive(RuntimeDebug, PartialEq, Eq, Encode, Decode, Clone, TypeInfo, Serialize, Deserialize)]
83
pub enum ProfileMode {
84
328
    Bootnode,
85
10
    Rpc { supports_ethereum_rpcs: bool },
86
}
87

            
88
/// Profile with additional data:
89
/// - the account id which created (and manage) the profile
90
/// - the amount deposited to register the profile
91
#[derive(
92
    RuntimeDebugNoBound,
93
    PartialEqNoBound,
94
    EqNoBound,
95
    Encode,
96
    Decode,
97
    CloneNoBound,
98
880
    TypeInfo,
99
    Serialize,
100
    Deserialize,
101
)]
102
#[scale_info(skip_type_params(T))]
103
pub struct RegisteredProfile<T: Config> {
104
    pub account: T::AccountId,
105
    pub deposit: BalanceOf<T>,
106
    pub profile: Profile<T>,
107
    /// There can be at most 1 assignment per profile.
108
    pub assignment: Option<(ParaId, AssignmentWitnessOf<T>)>,
109
}
110

            
111
/// Allows to process various kinds of payment options for assignments.
112
pub trait AssignmentPayment<AccountId> {
113
    /// Providers requests which kind of payment it accepts.
114
    type ProviderRequest: FullCodec
115
        + TypeInfo
116
        + Copy
117
        + Clone
118
        + Debug
119
        + Eq
120
        + Serialize
121
        + DeserializeOwned;
122
    /// Extra parameter the assigner provides.
123
    type AssignerParameter: FullCodec
124
        + TypeInfo
125
        + Copy
126
        + Clone
127
        + Debug
128
        + Eq
129
        + Serialize
130
        + DeserializeOwned;
131
    /// Represents the succesful outcome of the assignment.
132
    type AssignmentWitness: FullCodec
133
        + TypeInfo
134
        + Copy
135
        + Clone
136
        + Debug
137
        + Eq
138
        + Serialize
139
        + DeserializeOwned;
140

            
141
    fn try_start_assignment(
142
        assigner: AccountId,
143
        provider: AccountId,
144
        request: &Self::ProviderRequest,
145
        extra: Self::AssignerParameter,
146
    ) -> Result<Self::AssignmentWitness, DispatchErrorWithPostInfo>;
147

            
148
    fn try_stop_assignment(
149
        provider: AccountId,
150
        witness: Self::AssignmentWitness,
151
    ) -> Result<(), DispatchErrorWithPostInfo>;
152

            
153
    /// Return the values for a free assignment if it is supported.
154
    /// This is required to perform automatic migration from old Bootnodes storage.
155
    fn free_variant_values() -> Option<(
156
        Self::ProviderRequest,
157
        Self::AssignerParameter,
158
        Self::AssignmentWitness,
159
    )>;
160

            
161
    // The values returned by the following functions should match with each other.
162
    #[cfg(feature = "runtime-benchmarks")]
163
    fn benchmark_provider_request() -> Self::ProviderRequest;
164

            
165
    #[cfg(feature = "runtime-benchmarks")]
166
    fn benchmark_assigner_parameter() -> Self::AssignerParameter;
167

            
168
    #[cfg(feature = "runtime-benchmarks")]
169
    fn benchmark_assignment_witness() -> Self::AssignmentWitness;
170
}