Lines
26.32 %
Functions
6.9 %
Branches
100 %
// Copyright (C) Moondance Labs Ltd.
// This file is part of Tanssi.
// Tanssi is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Tanssi is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Tanssi. If not, see <http://www.gnu.org/licenses/>
use {
super::*,
dp_core::ParaId,
frame_support::{dispatch::DispatchErrorWithPostInfo, pallet_prelude::*},
serde::{de::DeserializeOwned, Serialize},
tp_traits::{apply, derive_scale_codec, derive_storage_traits},
};
pub type StringOf<T> = BoundedVec<u8, <T as Config>::MaxStringLen>;
pub type StringListOf<T> = BoundedVec<StringOf<T>, <T as Config>::MaxNodeUrlCount>;
#[apply(derive_scale_codec)]
#[derive(RuntimeDebugNoBound, PartialEqNoBound, EqNoBound, CloneNoBound, MaxEncodedLen)]
#[scale_info(skip_type_params(T))]
pub struct Profile<T: Config> {
/// Which para ids this profile is willing to accept providing services to.
pub para_ids: ParaIdsFilter<T>,
/// Specifies how the profile is willing to be assigned, mainly in terms of payment.
pub assignment_request: ProviderRequestOf<T>,
/// URLs to directly connect to this node RPC. Multiple URLs can be used to expose different
/// protocols (ws, wss, https, etc).
pub direct_rpc_urls: StringListOf<T>,
/// URLs to connect to a proxy/load balancer represented by this profile. Multiple URLs can be
/// used to expose different protocols (ws, wss, https, etc).
pub proxy_rpc_urls: StringListOf<T>,
/// URL to connect to the node as a bootnode. URL should be in MultiAddress format.
pub bootnode_url: Option<StringOf<T>>,
/// Kind of node this profile is running, which determines which services it can provide.
pub node_type: NodeType,
/// Freeform field to provide additional informations.
pub additional_info: StringOf<T>,
}
impl<T: Config> Profile<T> {
pub fn strings_len(&self) -> usize {
let mut len = 0;
len += self.direct_rpc_urls.iter().map(|x| x.len()).sum::<usize>();
len += self.proxy_rpc_urls.iter().map(|x| x.len()).sum::<usize>();
len += self.bootnode_url.iter().map(|x| x.len()).sum::<usize>();
len += self.additional_info.len();
len
pub enum ParaIdsFilter<T: Config> {
AnyParaId,
Whitelist(BoundedBTreeSet<ParaId, T::MaxParaIdsVecLen>),
Blacklist(BoundedBTreeSet<ParaId, T::MaxParaIdsVecLen>),
impl<T: Config> ParaIdsFilter<T> {
#[allow(clippy::len_without_is_empty)]
pub fn len(&self) -> usize {
match self {
Self::AnyParaId => 0,
Self::Whitelist(list) | Self::Blacklist(list) => list.len(),
pub fn can_assign(&self, para_id: &ParaId) -> bool {
ParaIdsFilter::AnyParaId => true,
ParaIdsFilter::Whitelist(list) => list.contains(para_id),
ParaIdsFilter::Blacklist(list) => !list.contains(para_id),
#[apply(derive_storage_traits)]
#[derive(MaxEncodedLen, DecodeWithMemTracking)]
pub enum NodeType {
Substrate,
Frontier,
/// Profile with additional data:
/// - the account id which created (and manage) the profile
/// - the amount deposited to register the profile
pub struct RegisteredProfile<T: Config> {
pub account: T::AccountId,
pub deposit: BalanceOf<T>,
pub profile: Profile<T>,
/// There can be at most 1 assignment per profile.
pub assignment: Option<(ParaId, AssignmentWitnessOf<T>)>,
/// Allows to process various kinds of payment options for assignments.
pub trait AssignmentProcessor<AccountId> {
/// Providers requests which kind of payment it accepts.
type ProviderRequest: tp_traits::StorageTraits + Serialize + DeserializeOwned + MaxEncodedLen;
/// Extra parameter the assigner provides.
type AssignerParameter: tp_traits::StorageTraits + Serialize + DeserializeOwned;
/// Represents the succesful outcome of the assignment.
type AssignmentWitness: tp_traits::StorageTraits + Serialize + DeserializeOwned + MaxEncodedLen;
fn try_start_assignment(
assigner: AccountId,
provider: AccountId,
request: &Self::ProviderRequest,
extra: Self::AssignerParameter,
) -> Result<Self::AssignmentWitness, DispatchErrorWithPostInfo>;
fn try_stop_assignment(
witness: Self::AssignmentWitness,
) -> Result<(), DispatchErrorWithPostInfo>;
// The values returned by the following functions should match with each other.
#[cfg(feature = "runtime-benchmarks")]
fn benchmark_provider_request() -> Self::ProviderRequest;
fn benchmark_assigner_parameter() -> Self::AssignerParameter;
fn benchmark_assignment_witness() -> Self::AssignmentWitness;