diff --git a/.github/workflows/benchmark-prs.yml b/.github/workflows/benchmark-prs.yml index 9eeac7683f..99e23211d1 100644 --- a/.github/workflows/benchmark-prs.yml +++ b/.github/workflows/benchmark-prs.yml @@ -54,7 +54,6 @@ jobs: node-path: target/release/safenode faucet-path: target/release/faucet platform: ubuntu-latest - build: true - name: Check SAFE_PEERS was set shell: bash diff --git a/.github/workflows/memcheck.yml b/.github/workflows/memcheck.yml index 19ed865d8a..842067ee43 100644 --- a/.github/workflows/memcheck.yml +++ b/.github/workflows/memcheck.yml @@ -65,7 +65,7 @@ jobs: - name: Start a local network env: - SN_LOG: all + SN_LOG: "all" uses: maidsafe/sn-local-testnet-action@main with: action: start @@ -74,7 +74,6 @@ jobs: faucet-path: target/release/faucet platform: ubuntu-latest set-safe-peers: false - build: true join: true # In this case we did *not* want SAFE_PEERS to be set to another value by starting the testnet diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml index dae183ef05..d1a9e9562a 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -153,7 +153,6 @@ jobs: node-path: target/release/safenode faucet-path: target/release/faucet platform: ${{ matrix.os }} - build: true - name: Check SAFE_PEERS was set shell: bash @@ -279,7 +278,6 @@ jobs: action: stop log_file_prefix: safe_test_logs_e2e platform: ${{ matrix.os }} - build: true gossipsub: if: "!startsWith(github.event.head_commit.message, 'chore(release):')" @@ -311,7 +309,6 @@ jobs: node-path: target/release/safenode faucet-path: target/release/faucet platform: ${{ matrix.os }} - build: true - name: Gossipsub - nodes to subscribe to topics, and publish messages run: cargo test --release -p sn_node --features local-discovery --test msgs_over_gossipsub -- --nocapture @@ -324,7 +321,6 @@ jobs: action: stop log_file_prefix: safe_test_logs_gossipsub_e2e platform: ${{ matrix.os }} - build: true spend_test: if: "!startsWith(github.event.head_commit.message, 'chore(release):')" @@ -357,7 +353,6 @@ jobs: node-path: target/release/safenode faucet-path: target/release/faucet platform: ${{ matrix.os }} - build: true - name: Check SAFE_PEERS was set shell: bash @@ -396,7 +391,6 @@ jobs: action: stop log_file_prefix: safe_test_logs_spend platform: ${{ matrix.os }} - build: true churn: if: "!startsWith(github.event.head_commit.message, 'chore(release):')" @@ -437,7 +431,6 @@ jobs: node-path: target/release/safenode faucet-path: target/release/faucet platform: ${{ matrix.os }} - build: true - name: Check SAFE_PEERS was set shell: bash @@ -464,7 +457,6 @@ jobs: action: stop log_file_prefix: safe_test_logs_churn platform: ${{ matrix.os }} - build: true - name: Verify restart of nodes using rg shell: bash @@ -559,7 +551,6 @@ jobs: node-path: target/release/safenode faucet-path: target/release/faucet platform: ${{ matrix.os }} - build: true - name: Check SAFE_PEERS was set shell: bash @@ -593,7 +584,6 @@ jobs: action: stop log_file_prefix: safe_test_logs_data_location platform: ${{ matrix.os }} - build: true - name: Verify restart of nodes using rg shell: bash @@ -769,7 +759,6 @@ jobs: node-path: target/release/safenode faucet-path: target/release/faucet platform: ubuntu-latest - build: true - name: Check SAFE_PEERS was set shell: bash @@ -861,4 +850,3 @@ jobs: action: stop log_file_prefix: safe_test_logs_heavy_replicate_bench platform: ubuntu-latest - build: true \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2f80084efc..9d0d7dd560 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -38,9 +38,6 @@ jobs: target: aarch64-unknown-linux-musl steps: - uses: actions/checkout@v4 - - - - uses: dtolnay/rust-toolchain@stable # It's quite slow to install just by building it, but here we need a cross-platform solution. - shell: bash @@ -75,8 +72,6 @@ jobs: GH_TOKEN: ${{ secrets.VERSION_BUMP_COMMIT_PAT }} steps: - - - uses: actions/checkout@v4 with: fetch-depth: "0" diff --git a/sn_node/tests/common/client.rs b/sn_node/tests/common/client.rs index ffbd81c30f..8a33eb5320 100644 --- a/sn_node/tests/common/client.rs +++ b/sn_node/tests/common/client.rs @@ -10,6 +10,7 @@ use eyre::{bail, Result}; use lazy_static::lazy_static; use sn_client::{send, Client}; use sn_peers_acquisition::parse_peer_addr; +use sn_protocol::node_registry::{get_local_node_registry_path, NodeRegistry}; use sn_protocol::test_utils::DeploymentInventory; use sn_transfers::{create_faucet_wallet, LocalWallet, NanoTokens, Transfer}; use std::{ @@ -53,18 +54,13 @@ pub fn get_all_rpc_addresses() -> Result> { match DeploymentInventory::load() { Ok(inventory) => Ok(inventory.rpc_endpoints), Err(_) => { - let starting_port = match std::env::var("CHURN_TEST_START_PORT") { - Ok(val) => val.parse()?, - Err(_) => 12000, - }; - let mut addresses = Vec::new(); - for i in 1..LOCAL_NODE_COUNT + 1 { - let addr = SocketAddr::new( - IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), - starting_port + i as u16, - ); - addresses.push(addr); - } + let local_node_reg_path = &get_local_node_registry_path()?; + let local_node_registry = NodeRegistry::load(local_node_reg_path)?; + let addresses = local_node_registry + .nodes + .iter() + .map(|n| SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), n.rpc_port)) + .collect::>(); Ok(addresses) } } diff --git a/sn_protocol/Cargo.toml b/sn_protocol/Cargo.toml index f3273970d4..f4df6c16e2 100644 --- a/sn_protocol/Cargo.toml +++ b/sn_protocol/Cargo.toml @@ -10,7 +10,7 @@ repository = "https://github.com/maidsafe/safe_network" version = "0.10.7" [features] -test-utils=["dirs-next", "serde_json"] +test-utils=[] [dependencies] bls = { package = "blsttc", version = "8.0.1" } @@ -18,12 +18,12 @@ bytes = { version = "1.0.1", features = ["serde"] } color-eyre = "0.6.2" crdts = { version = "7.3", default-features = false, features = ["merkle"] } custom_debug = "~0.5.0" -dirs-next = { version = "~2.0.0", optional = true } +dirs-next = "~2.0.0" hex = "~0.4.3" libp2p = { version="0.53", features = ["identify", "kad"] } rmp-serde = "1.1.1" serde = { version = "1.0.133", features = [ "derive", "rc" ]} -serde_json = {version = "1.0", optional = true } +serde_json = "1.0" sha2 = "0.10.7" sn_transfers = { path = "../sn_transfers", version = "0.14.37" } sn_registers = { path = "../sn_registers", version = "0.3.7" } diff --git a/sn_protocol/src/error.rs b/sn_protocol/src/error.rs index 87d2dea4af..7200a59e07 100644 --- a/sn_protocol/src/error.rs +++ b/sn_protocol/src/error.rs @@ -17,6 +17,10 @@ pub type Result = std::result::Result; #[derive(Error, Clone, PartialEq, Eq, Serialize, Deserialize, custom_debug::Debug)] #[non_exhaustive] pub enum Error { + // ---------- Misc errors + #[error("Could not obtain user's data directory")] + UserDataDirectoryNotObtainable, + // ---------- Chunk Proof errors #[error("Chunk does not exist {0:?}")] ChunkDoesNotExist(NetworkAddress), diff --git a/sn_protocol/src/lib.rs b/sn_protocol/src/lib.rs index 194e716080..1686ea9cc2 100644 --- a/sn_protocol/src/lib.rs +++ b/sn_protocol/src/lib.rs @@ -13,6 +13,8 @@ extern crate tracing; pub mod error; /// Messages types pub mod messages; +/// Data structures for node management. +pub mod node_registry; /// RPC commands to node pub mod node_rpc; /// Storage types for spends, chunks and registers. diff --git a/sn_protocol/src/node_registry.rs b/sn_protocol/src/node_registry.rs new file mode 100644 index 0000000000..4e96e52e46 --- /dev/null +++ b/sn_protocol/src/node_registry.rs @@ -0,0 +1,125 @@ +// Copyright (C) 2024 MaidSafe.net limited. +// +// This SAFE Network Software is licensed to you under The General Public License (GPL), version 3. +// Unless required by applicable law or agreed to in writing, the SAFE Network Software distributed +// under the GPL Licence is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. Please review the Licences for the specific language governing +// permissions and limitations relating to use of the SAFE Network Software. + +use crate::Error; +use color_eyre::Result; +use libp2p::{Multiaddr, PeerId}; +use serde::de::Error as DeError; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; +use std::io::{Read, Write}; +use std::path::{Path, PathBuf}; +use std::str::FromStr; + +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +pub enum NodeStatus { + /// The node service has been added but not started for the first time + Added, + /// Last time we checked the service was running + Running, + /// The node service has been stopped + Stopped, + /// The node service has been removed + Removed, +} + +fn serialize_peer_id(value: &Option, serializer: S) -> Result +where + S: Serializer, +{ + if let Some(peer_id) = value { + return serializer.serialize_str(&peer_id.to_string()); + } + serializer.serialize_none() +} + +fn deserialize_peer_id<'de, D>(deserializer: D) -> Result, D::Error> +where + D: Deserializer<'de>, +{ + let s: Option = Option::deserialize(deserializer)?; + if let Some(peer_id_str) = s { + PeerId::from_str(&peer_id_str) + .map(Some) + .map_err(DeError::custom) + } else { + Ok(None) + } +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Node { + pub genesis: bool, + pub version: String, + pub service_name: String, + pub user: String, + pub number: u16, + pub port: u16, + pub rpc_port: u16, + pub status: NodeStatus, + pub pid: Option, + #[serde( + serialize_with = "serialize_peer_id", + deserialize_with = "deserialize_peer_id" + )] + pub peer_id: Option, + pub data_dir_path: Option, + pub log_dir_path: Option, + pub safenode_path: Option, +} + +impl Node { + pub fn get_multiaddr(&self) -> Option { + if let Some(peer_id) = self.peer_id { + let peer = format!("/ip4/127.0.0.1/tcp/{}/p2p/{}", self.port, peer_id); + match peer.parse() { + Ok(p) => return Some(p), + Err(_) => return None, + } + } + None + } +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct NodeRegistry { + pub save_path: PathBuf, + pub nodes: Vec, + pub faucet_pid: Option, +} + +impl NodeRegistry { + pub fn save(&self) -> Result<()> { + let json = serde_json::to_string(self)?; + let mut file = std::fs::File::create(self.save_path.clone())?; + file.write_all(json.as_bytes())?; + Ok(()) + } + + pub fn load(path: &Path) -> Result { + if !path.exists() { + return Ok(NodeRegistry { + save_path: path.to_path_buf(), + nodes: vec![], + faucet_pid: None, + }); + } + let mut file = std::fs::File::open(path)?; + let mut contents = String::new(); + file.read_to_string(&mut contents)?; + let registry = serde_json::from_str(&contents)?; + Ok(registry) + } +} + +pub fn get_local_node_registry_path() -> Result { + let path = dirs_next::data_dir() + .ok_or_else(|| Error::UserDataDirectoryNotObtainable)? + .join("safe") + .join("local_node_registry.json"); + Ok(path) +}