mirror of
https://git.ghostchain.io/proxmio/ghost-node.git
synced 2025-12-27 11:19:57 +00:00
inital commit, which is clearly not initial
Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
This commit is contained in:
538
pallets/networks/src/lib.rs
Executable file
538
pallets/networks/src/lib.rs
Executable file
@@ -0,0 +1,538 @@
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
#![allow(clippy::large_enum_variant)]
|
||||
#![allow(clippy::too_many_arguments)]
|
||||
|
||||
use frame_support::{
|
||||
pallet_prelude::*,
|
||||
storage::PrefixIterator, traits::EnsureOrigin,
|
||||
};
|
||||
use frame_system::pallet_prelude::*;
|
||||
use scale_info::TypeInfo;
|
||||
use sp_runtime::{
|
||||
traits::{AtLeast32BitUnsigned, Member},
|
||||
DispatchResult,
|
||||
};
|
||||
use sp_std::prelude::*;
|
||||
|
||||
pub use ghost_traits::networks::{
|
||||
NetworkDataBasicHandler, NetworkDataInspectHandler,
|
||||
NetworkDataMutateHandler,
|
||||
};
|
||||
|
||||
mod weights;
|
||||
|
||||
pub use module::*;
|
||||
pub use crate::weights::WeightInfo;
|
||||
|
||||
#[cfg(any(feature = "runtime-benchmarks", test))]
|
||||
mod benchmarking;
|
||||
#[cfg(all(feature = "std", test))]
|
||||
mod mock;
|
||||
#[cfg(all(feature = "std", test))]
|
||||
mod tests;
|
||||
|
||||
#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)]
|
||||
pub enum NetworkType {
|
||||
Evm = 0,
|
||||
Utxo = 1,
|
||||
Undefined = 2,
|
||||
}
|
||||
|
||||
impl Default for NetworkType {
|
||||
fn default() -> Self { NetworkType::Evm }
|
||||
}
|
||||
|
||||
#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)]
|
||||
pub struct NetworkData {
|
||||
pub chain_name: Vec<u8>,
|
||||
pub default_endpoint: Vec<u8>,
|
||||
pub gatekeeper: Vec<u8>,
|
||||
pub topic_name: Vec<u8>,
|
||||
pub finality_delay: Option<u64>,
|
||||
pub release_delay: Option<u64>,
|
||||
pub network_type: NetworkType,
|
||||
pub incoming_fee: u32,
|
||||
pub outgoing_fee: u32,
|
||||
}
|
||||
|
||||
#[frame_support::pallet]
|
||||
pub mod module {
|
||||
use super::*;
|
||||
|
||||
#[pallet::config]
|
||||
pub trait Config: frame_system::Config {
|
||||
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
|
||||
|
||||
/// The type used as a unique network id.
|
||||
type NetworkId: Parameter
|
||||
+ Member
|
||||
+ Parameter
|
||||
+ AtLeast32BitUnsigned
|
||||
+ Default
|
||||
+ Copy
|
||||
+ Ord
|
||||
+ TypeInfo
|
||||
+ MaybeSerializeDeserialize
|
||||
+ MaxEncodedLen;
|
||||
|
||||
/// The origin required to register new network.
|
||||
type RegisterOrigin: EnsureOrigin<Self::RuntimeOrigin>;
|
||||
/// The origin required to update network information.
|
||||
type UpdateOrigin: EnsureOrigin<Self::RuntimeOrigin>;
|
||||
/// The origin required to remove network.
|
||||
type RemoveOrigin: EnsureOrigin<Self::RuntimeOrigin>;
|
||||
|
||||
/// Weight information for extrinsics in this module.
|
||||
type WeightInfo: WeightInfo;
|
||||
}
|
||||
|
||||
#[pallet::error]
|
||||
pub enum Error<T> {
|
||||
/// Network already registered.
|
||||
NetworkAlreadyRegistered,
|
||||
/// Network does not exist.
|
||||
NetworkDoesNotExist,
|
||||
/// Gatekeeper address length not 42 or prefix `0x` missed.
|
||||
WrongGatekeeperAddress,
|
||||
/// Topic name length not 66 or prefix `0x` missed.
|
||||
WrongTopicName,
|
||||
}
|
||||
|
||||
#[pallet::event]
|
||||
#[pallet::generate_deposit(pub(crate) fn deposit_event)]
|
||||
pub enum Event<T: Config> {
|
||||
NetworkRegistered { chain_id: T::NetworkId, network: NetworkData },
|
||||
NetworkNameUpdated { chain_id: T::NetworkId, chain_name: Vec<u8> },
|
||||
NetworkEndpointUpdated { chain_id: T::NetworkId, default_endpoint: Vec<u8> },
|
||||
NetworkFinalityDelayUpdated { chain_id: T::NetworkId, finality_delay: Option<u64> },
|
||||
NetworkReleaseDelayUpdated { chain_id: T::NetworkId, release_delay: Option<u64> },
|
||||
NetworkTypeUpdated { chain_id: T::NetworkId, network_type: NetworkType },
|
||||
NetworkGatekeeperUpdated { chain_id: T::NetworkId, gatekeeper: Vec<u8> },
|
||||
NetworkTopicNameUpdated { chain_id: T::NetworkId, topic_name: Vec<u8> },
|
||||
NetworkIncomingFeeUpdated { chain_id: T::NetworkId, incoming_fee: u32 },
|
||||
NetworkOutgoingFeeUpdated { chain_id: T::NetworkId, outgoing_fee: u32 },
|
||||
NetworkRemoved { chain_id: T::NetworkId },
|
||||
}
|
||||
|
||||
#[pallet::storage]
|
||||
#[pallet::getter(fn networks)]
|
||||
pub type Networks<T: Config> =
|
||||
StorageMap<_, Twox64Concat, T::NetworkId, NetworkData, OptionQuery>;
|
||||
|
||||
#[pallet::genesis_config]
|
||||
pub struct GenesisConfig<T: Config> {
|
||||
pub networks: Vec<(T::NetworkId, Vec<u8>)>,
|
||||
}
|
||||
|
||||
impl<T: Config> Default for GenesisConfig<T> {
|
||||
fn default() -> Self {
|
||||
Self { networks: vec![] }
|
||||
}
|
||||
}
|
||||
|
||||
#[pallet::genesis_build]
|
||||
impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {
|
||||
fn build(&self) {
|
||||
if !self.networks.is_empty() {
|
||||
self.networks.iter().for_each(|(chain_id, network_metadata)| {
|
||||
let network =
|
||||
NetworkData::decode(&mut &network_metadata[..])
|
||||
.expect("Error decoding NetworkData");
|
||||
Pallet::<T>::do_register_network(chain_id.clone(), network)
|
||||
.expect("Error registering network");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[pallet::pallet]
|
||||
#[pallet::without_storage_info]
|
||||
pub struct Pallet<T>(PhantomData<T>);
|
||||
|
||||
#[pallet::hooks]
|
||||
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {}
|
||||
|
||||
#[pallet::call]
|
||||
impl<T: Config> Pallet<T> {
|
||||
#[pallet::call_index(0)]
|
||||
#[pallet::weight(T::WeightInfo::register_network(
|
||||
network.chain_name.len() as u32,
|
||||
network.default_endpoint.len() as u32,
|
||||
))]
|
||||
pub fn register_network(
|
||||
origin: OriginFor<T>,
|
||||
chain_id: T::NetworkId,
|
||||
network: NetworkData,
|
||||
) -> DispatchResult {
|
||||
T::RegisterOrigin::ensure_origin_or_root(origin)?;
|
||||
Self::do_register_network(chain_id, network)
|
||||
}
|
||||
|
||||
#[pallet::call_index(1)]
|
||||
#[pallet::weight(T::WeightInfo::update_network_name(
|
||||
chain_name.len() as u32,
|
||||
))]
|
||||
pub fn update_network_name(
|
||||
origin: OriginFor<T>,
|
||||
chain_id: T::NetworkId,
|
||||
chain_name: Vec<u8>,
|
||||
) -> DispatchResult {
|
||||
T::UpdateOrigin::ensure_origin_or_root(origin)?;
|
||||
Self::do_update_network_name(
|
||||
chain_id,
|
||||
chain_name,
|
||||
)
|
||||
}
|
||||
|
||||
#[pallet::call_index(2)]
|
||||
#[pallet::weight(T::WeightInfo::update_network_endpoint(
|
||||
default_endpoint.len() as u32
|
||||
))]
|
||||
pub fn update_network_endpoint(
|
||||
origin: OriginFor<T>,
|
||||
chain_id: T::NetworkId,
|
||||
default_endpoint: Vec<u8>,
|
||||
) -> DispatchResult {
|
||||
T::UpdateOrigin::ensure_origin_or_root(origin)?;
|
||||
Self::do_update_network_endpoint(
|
||||
chain_id,
|
||||
default_endpoint,
|
||||
)
|
||||
}
|
||||
|
||||
#[pallet::call_index(3)]
|
||||
#[pallet::weight(T::WeightInfo::update_network_finality_delay())]
|
||||
pub fn update_network_finality_delay(
|
||||
origin: OriginFor<T>,
|
||||
chain_id: T::NetworkId,
|
||||
finality_delay: Option<u64>,
|
||||
) -> DispatchResult {
|
||||
T::UpdateOrigin::ensure_origin_or_root(origin)?;
|
||||
Self::do_update_network_finality_delay(
|
||||
chain_id,
|
||||
finality_delay,
|
||||
)
|
||||
}
|
||||
|
||||
#[pallet::call_index(4)]
|
||||
#[pallet::weight(T::WeightInfo::update_network_release_delay())]
|
||||
pub fn update_network_release_delay(
|
||||
origin: OriginFor<T>,
|
||||
chain_id: T::NetworkId,
|
||||
release_delay: Option<u64>,
|
||||
) -> DispatchResult {
|
||||
T::UpdateOrigin::ensure_origin_or_root(origin)?;
|
||||
Self::do_update_network_release_delay(
|
||||
chain_id,
|
||||
release_delay,
|
||||
)
|
||||
}
|
||||
|
||||
#[pallet::call_index(5)]
|
||||
#[pallet::weight(T::WeightInfo::update_network_type())]
|
||||
pub fn update_network_type(
|
||||
origin: OriginFor<T>,
|
||||
chain_id: T::NetworkId,
|
||||
network_type: NetworkType,
|
||||
) -> DispatchResult {
|
||||
T::UpdateOrigin::ensure_origin_or_root(origin)?;
|
||||
Self::do_update_network_type(
|
||||
chain_id,
|
||||
network_type,
|
||||
)
|
||||
}
|
||||
|
||||
#[pallet::call_index(6)]
|
||||
#[pallet::weight(T::WeightInfo::update_network_gatekeeper())]
|
||||
pub fn update_network_gatekeeper(
|
||||
origin: OriginFor<T>,
|
||||
chain_id: T::NetworkId,
|
||||
gatekeeper: Vec<u8>,
|
||||
) -> DispatchResult {
|
||||
T::UpdateOrigin::ensure_origin_or_root(origin)?;
|
||||
Self::do_update_network_gatekeeper(
|
||||
chain_id,
|
||||
gatekeeper,
|
||||
)
|
||||
}
|
||||
|
||||
#[pallet::call_index(7)]
|
||||
#[pallet::weight(T::WeightInfo::update_network_topic_name())]
|
||||
pub fn update_network_topic_name(
|
||||
origin: OriginFor<T>,
|
||||
chain_id: T::NetworkId,
|
||||
topic_name: Vec<u8>,
|
||||
) -> DispatchResult {
|
||||
T::UpdateOrigin::ensure_origin_or_root(origin)?;
|
||||
Self::do_update_network_topic_name(
|
||||
chain_id,
|
||||
topic_name,
|
||||
)
|
||||
}
|
||||
|
||||
#[pallet::call_index(8)]
|
||||
#[pallet::weight(T::WeightInfo::update_incoming_network_fee())]
|
||||
pub fn update_incoming_network_fee(
|
||||
origin: OriginFor<T>,
|
||||
chain_id: T::NetworkId,
|
||||
incoming_fee: u32,
|
||||
) -> DispatchResult {
|
||||
T::UpdateOrigin::ensure_origin_or_root(origin)?;
|
||||
Self::do_update_incoming_network_fee(
|
||||
chain_id,
|
||||
incoming_fee,
|
||||
)
|
||||
}
|
||||
|
||||
#[pallet::call_index(9)]
|
||||
#[pallet::weight(T::WeightInfo::update_outgoing_network_fee())]
|
||||
pub fn update_outgoing_network_fee(
|
||||
origin: OriginFor<T>,
|
||||
chain_id: T::NetworkId,
|
||||
outgoing_fee: u32,
|
||||
) -> DispatchResult {
|
||||
T::UpdateOrigin::ensure_origin_or_root(origin)?;
|
||||
Self::do_update_outgoing_network_fee(
|
||||
chain_id,
|
||||
outgoing_fee,
|
||||
)
|
||||
}
|
||||
|
||||
#[pallet::call_index(10)]
|
||||
#[pallet::weight(T::WeightInfo::remove_network())]
|
||||
pub fn remove_network(
|
||||
origin: OriginFor<T>,
|
||||
chain_id: T::NetworkId,
|
||||
) -> DispatchResult {
|
||||
T::RemoveOrigin::ensure_origin_or_root(origin)?;
|
||||
Self::do_remove_network(chain_id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config> Pallet<T> {
|
||||
/// Register a new network.
|
||||
pub fn do_register_network(
|
||||
chain_id: T::NetworkId,
|
||||
network: NetworkData,
|
||||
) -> DispatchResult {
|
||||
Networks::<T>::try_mutate(&chain_id, |maybe_network| -> DispatchResult {
|
||||
ensure!(maybe_network.is_none(), Error::<T>::NetworkAlreadyRegistered);
|
||||
*maybe_network = Some(network.clone());
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
Self::deposit_event(Event::<T>::NetworkRegistered { chain_id, network });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Remove existent network.
|
||||
pub fn do_remove_network(chain_id: T::NetworkId) -> DispatchResult {
|
||||
Networks::<T>::try_mutate(&chain_id, |maybe_network| -> DispatchResult {
|
||||
ensure!(maybe_network.is_some(), Error::<T>::NetworkDoesNotExist);
|
||||
*maybe_network = None;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
Self::deposit_event(Event::<T>::NetworkRemoved { chain_id });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Update existent network name.
|
||||
pub fn do_update_network_name(
|
||||
chain_id: T::NetworkId,
|
||||
chain_name: Vec<u8>,
|
||||
) -> DispatchResult {
|
||||
Networks::<T>::try_mutate(&chain_id, |maybe_network| -> DispatchResult {
|
||||
ensure!(maybe_network.is_some(), Error::<T>::NetworkDoesNotExist);
|
||||
let net = maybe_network.as_mut().unwrap();
|
||||
net.chain_name = chain_name.clone();
|
||||
*maybe_network = Some(net.clone());
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
Self::deposit_event(Event::<T>::NetworkNameUpdated {
|
||||
chain_id,
|
||||
chain_name,
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Update existent network default endpoint.
|
||||
pub fn do_update_network_endpoint(
|
||||
chain_id: T::NetworkId,
|
||||
default_endpoint: Vec<u8>,
|
||||
) -> DispatchResult {
|
||||
Networks::<T>::try_mutate(&chain_id, |maybe_network| -> DispatchResult {
|
||||
ensure!(maybe_network.is_some(), Error::<T>::NetworkDoesNotExist);
|
||||
let net = maybe_network.as_mut().unwrap();
|
||||
net.default_endpoint = default_endpoint.clone();
|
||||
*maybe_network = Some(net.clone());
|
||||
Ok(())
|
||||
})?;
|
||||
Self::deposit_event(Event::<T>::NetworkEndpointUpdated {
|
||||
chain_id,
|
||||
default_endpoint,
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Update existent network default endpoint.
|
||||
pub fn do_update_network_finality_delay(
|
||||
chain_id: T::NetworkId,
|
||||
finality_delay: Option<u64>,
|
||||
) -> DispatchResult {
|
||||
Networks::<T>::try_mutate(&chain_id, |maybe_network| -> DispatchResult {
|
||||
ensure!(maybe_network.is_some(), Error::<T>::NetworkDoesNotExist);
|
||||
let net = maybe_network.as_mut().unwrap();
|
||||
net.finality_delay = finality_delay;
|
||||
*maybe_network = Some(net.clone());
|
||||
Ok(())
|
||||
})?;
|
||||
Self::deposit_event(Event::<T>::NetworkFinalityDelayUpdated {
|
||||
chain_id,
|
||||
finality_delay,
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Update existent network default endpoint.
|
||||
pub fn do_update_network_release_delay(
|
||||
chain_id: T::NetworkId,
|
||||
release_delay: Option<u64>,
|
||||
) -> DispatchResult {
|
||||
Networks::<T>::try_mutate(&chain_id, |maybe_network| -> DispatchResult {
|
||||
ensure!(maybe_network.is_some(), Error::<T>::NetworkDoesNotExist);
|
||||
let net = maybe_network.as_mut().unwrap();
|
||||
net.release_delay = release_delay;
|
||||
*maybe_network = Some(net.clone());
|
||||
Ok(())
|
||||
})?;
|
||||
Self::deposit_event(Event::<T>::NetworkReleaseDelayUpdated {
|
||||
chain_id,
|
||||
release_delay,
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Update existent network type.
|
||||
pub fn do_update_network_type(
|
||||
chain_id: T::NetworkId,
|
||||
network_type: NetworkType,
|
||||
) -> DispatchResult {
|
||||
Networks::<T>::try_mutate(&chain_id, |maybe_network| -> DispatchResult {
|
||||
ensure!(maybe_network.is_some(), Error::<T>::NetworkDoesNotExist);
|
||||
let net = maybe_network.as_mut().unwrap();
|
||||
net.network_type = network_type.clone();
|
||||
*maybe_network = Some(net.clone());
|
||||
Ok(())
|
||||
})?;
|
||||
Self::deposit_event(Event::<T>::NetworkTypeUpdated {
|
||||
chain_id,
|
||||
network_type,
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Update existent network gatekeeper.
|
||||
pub fn do_update_network_gatekeeper(
|
||||
chain_id: T::NetworkId,
|
||||
gatekeeper: Vec<u8>,
|
||||
) -> DispatchResult {
|
||||
ensure!(gatekeeper.len() == 42 && gatekeeper[0] == 48 && gatekeeper[1] == 120,
|
||||
Error::<T>::WrongGatekeeperAddress);
|
||||
Networks::<T>::try_mutate(&chain_id, |maybe_network| -> DispatchResult {
|
||||
ensure!(maybe_network.is_some(), Error::<T>::NetworkDoesNotExist);
|
||||
let net = maybe_network.as_mut().unwrap();
|
||||
net.gatekeeper = gatekeeper.clone();
|
||||
*maybe_network = Some(net.clone());
|
||||
Ok(())
|
||||
})?;
|
||||
Self::deposit_event(Event::<T>::NetworkGatekeeperUpdated {
|
||||
chain_id,
|
||||
gatekeeper,
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Update existent network gatekeeper's topic name.
|
||||
pub fn do_update_network_topic_name(
|
||||
chain_id: T::NetworkId,
|
||||
topic_name: Vec<u8>,
|
||||
) -> DispatchResult {
|
||||
ensure!(topic_name.len() == 66 && topic_name[0] == 48 && topic_name[1] == 120,
|
||||
Error::<T>::WrongTopicName);
|
||||
Networks::<T>::try_mutate(&chain_id, |maybe_network| -> DispatchResult {
|
||||
ensure!(maybe_network.is_some(), Error::<T>::NetworkDoesNotExist);
|
||||
let net = maybe_network.as_mut().unwrap();
|
||||
net.topic_name = topic_name.clone();
|
||||
*maybe_network = Some(net.clone());
|
||||
Ok(())
|
||||
})?;
|
||||
Self::deposit_event(Event::<T>::NetworkTopicNameUpdated {
|
||||
chain_id,
|
||||
topic_name,
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn do_update_incoming_network_fee(
|
||||
chain_id: T::NetworkId,
|
||||
incoming_fee: u32,
|
||||
) -> DispatchResult {
|
||||
Networks::<T>::try_mutate(&chain_id, |maybe_network| -> DispatchResult {
|
||||
ensure!(maybe_network.is_some(), Error::<T>::NetworkDoesNotExist);
|
||||
let net = maybe_network.as_mut().unwrap();
|
||||
net.incoming_fee = incoming_fee.clone();
|
||||
*maybe_network = Some(net.clone());
|
||||
Ok(())
|
||||
})?;
|
||||
Self::deposit_event(Event::<T>::NetworkIncomingFeeUpdated {
|
||||
chain_id,
|
||||
incoming_fee,
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn do_update_outgoing_network_fee(
|
||||
chain_id: T::NetworkId,
|
||||
outgoing_fee: u32,
|
||||
) -> DispatchResult {
|
||||
Networks::<T>::try_mutate(&chain_id, |maybe_network| -> DispatchResult {
|
||||
ensure!(maybe_network.is_some(), Error::<T>::NetworkDoesNotExist);
|
||||
let net = maybe_network.as_mut().unwrap();
|
||||
net.outgoing_fee = outgoing_fee.clone();
|
||||
*maybe_network = Some(net.clone());
|
||||
Ok(())
|
||||
})?;
|
||||
Self::deposit_event(Event::<T>::NetworkOutgoingFeeUpdated {
|
||||
chain_id,
|
||||
outgoing_fee,
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config> NetworkDataBasicHandler for Pallet<T> {
|
||||
type NetworkId = T::NetworkId;
|
||||
}
|
||||
|
||||
impl<T: Config> NetworkDataInspectHandler<NetworkData> for Pallet<T> {
|
||||
fn get(n: &Self::NetworkId) -> Option<NetworkData> {
|
||||
Networks::<T>::get(n)
|
||||
}
|
||||
|
||||
fn iter() -> PrefixIterator<(Self::NetworkId, NetworkData)> {
|
||||
Networks::<T>::iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config> NetworkDataMutateHandler<NetworkData> for Pallet<T> {
|
||||
fn register(chain_id: Self::NetworkId, network: NetworkData) -> DispatchResult {
|
||||
Self::do_register_network(chain_id, network)
|
||||
}
|
||||
|
||||
fn remove(chain_id: Self::NetworkId) -> DispatchResult {
|
||||
Self::do_remove_network(chain_id)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user