Skip to content
Snippets Groups Projects
Select Git revision
  • 8ed08060be083adb30b2b75d613c8fb99cd0e5bc
  • master default protected
  • ci-embed-raw-specs
  • network/gtest-1000 protected
  • upgradable-multisig
  • runtime/gtest-1000
  • network/gdev-800 protected
  • cgeek/issue-297-cpu
  • gdev-800-tests
  • update-docker-compose-rpc-squid-names
  • fix-252
  • 1000i100-test
  • hugo/tmp-0.9.1
  • network/gdev-803 protected
  • hugo/endpoint-gossip
  • network/gdev-802 protected
  • hugo/distance-precompute
  • network/gdev-900 protected
  • tuxmain/anonymous-tx
  • debug/podman
  • hugo/195-doc
  • gtest-1000-0.11.0 protected
  • gtest-1000 protected
  • gdev-900-0.10.1 protected
  • gdev-900-0.10.0 protected
  • gdev-900-0.9.2 protected
  • gdev-800-0.8.0 protected
  • gdev-900-0.9.1 protected
  • gdev-900-0.9.0 protected
  • gdev-803 protected
  • gdev-802 protected
  • runtime-801 protected
  • gdev-800 protected
  • runtime-800-bis protected
  • runtime-800 protected
  • runtime-800-backup protected
  • runtime-701 protected
  • runtime-700 protected
  • runtime-600 protected
  • runtime-500 protected
  • v0.4.1 protected
41 results

state.rs

Blame
  • state.rs 2.44 KiB
    use crate::endpoint_gossip::{
        handler::DuniterPeeringEvent, rpc::data::DuniterPeeringsData, DuniterEndpoint,
    };
    use codec::{Decode, Encode};
    use futures::StreamExt;
    use jsonrpsee::core::Serialize;
    use parking_lot::RwLock;
    use sc_utils::mpsc::{tracing_unbounded, TracingUnboundedSender};
    use serde::Deserialize;
    use std::sync::Arc;
    
    /// A struct to hold a peer endpoints along with its id for RPC exposure.
    #[derive(Encode, Decode, Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
    pub struct PeeringWithId {
        pub peer_id: String,
        pub endpoints: Vec<DuniterEndpoint>,
    }
    
    #[derive(Clone)]
    pub struct DuniterPeeringsState {
        inner: Arc<RwLock<Option<Box<DuniterPeeringsData>>>>,
    }
    
    /// Dummy CRUD operations for the state to be exposed, plus a listening sink to be notified of
    /// network events and automatically insert/remove peers from the state.
    impl DuniterPeeringsState {
        pub fn empty() -> Self {
            Self {
                inner: Arc::new(RwLock::new(Some(Box::new(DuniterPeeringsData {
                    peerings: Vec::new(),
                })))),
            }
        }
    
        pub fn insert(&self, peering: PeeringWithId) -> &Self {
            self.inner.write().as_mut().map(|vs| {
                vs.peerings.push(peering);
            });
            &self
        }
    
        pub fn remove(&self, peer_id: String) -> &Self {
            self.inner.write().as_mut().map(|vs| {
                vs.peerings.retain(|p| p.peer_id != peer_id);
            });
            &self
        }
    
        pub fn peer_state(&self) -> Option<DuniterPeeringsData> {
            self.inner.read().as_ref().map(|vs| vs.as_ref().clone())
        }
    
        /// Creates a channel for binding to the network events.
        pub fn listen(&self) -> TracingUnboundedSender<DuniterPeeringEvent> {
            let (sink, mut stream) = tracing_unbounded("mpsc_duniter_peering_rpc_stream", 1_000);
            let state = self.clone();
            tokio::spawn(async move {
                while let Some(event) = stream.next().await {
                    match event {
                        DuniterPeeringEvent::GoodPeering(who, peering) => {
                            state.insert(PeeringWithId {
                                peer_id: who.to_base58(),
                                endpoints: peering.endpoints,
                            });
                        }
                        DuniterPeeringEvent::StreamClosed(who) => {
                            state.remove(who.to_base58());
                        }
                        _ => {}
                    }
                }
            });
            sink
        }
    }