diff --git a/src/constants.rs b/src/constants.rs
index ea2d715..ec500cc 100644
--- a/src/constants.rs
+++ b/src/constants.rs
@@ -197,6 +197,9 @@ pub const P2POOL_LOG: &str = "Verbosity of the console log";
 pub const P2POOL_AUTO_NODE: &str = "Automatically ping the community Monero nodes at Gupax startup";
 pub const P2POOL_AUTO_SELECT: &str = "Automatically select the fastest community Monero node after pinging";
 pub const P2POOL_SELECT_FASTEST: &str = "Select the fastest community Monero node";
+pub const P2POOL_SELECT_RANDOM: &str = "Select a random community Monero node";
+pub const P2POOL_SELECT_LAST: &str = "Select the previous community Monero node";
+pub const P2POOL_SELECT_NEXT: &str = "Select the next community Monero node";
 pub const P2POOL_PING: &str = "Ping the built-in community Monero nodes";
 pub const P2POOL_ADDRESS: &str = "You must use a primary Monero address to mine on P2Pool (starts with a 4). It is highly recommended to create a new wallet since addresses are public on P2Pool!";
 pub const P2POOL_INPUT: &str = "Send a command to P2Pool";
diff --git a/src/node.rs b/src/node.rs
index cda079d..4f21cab 100644
--- a/src/node.rs
+++ b/src/node.rs
@@ -19,6 +19,7 @@ use crate::{
 	constants::*,
 };
 use serde::{Serialize,Deserialize};
+use rand::{thread_rng, Rng};
 use std::time::{Instant,Duration};
 use std::sync::{Arc,Mutex};
 use egui::Color32;
@@ -56,12 +57,88 @@ pub const NODE_IPS: [&str; 17] = [
 	MONERUJO,PLOWSOF_1,PLOWSOF_2,RINO,SETH,SUPPORTXMR,SUPPORTXMR_IR,XMRVSBEAST,
 ];
 
+pub const COMMUNITY_NODE_LENGTH: usize = NODE_IPS.len();
+
 #[derive(Copy,Clone,Eq,PartialEq,Debug,Deserialize,Serialize)]
 pub enum NodeEnum {
 	C3pool,Cake,CakeEu,CakeUk,CakeUs,MajesticBankIs,MajesticBankSu,Monerujo,Plowsof1,
 	Plowsof2,Rino,Feather1,Feather2,Seth,SupportXmr,SupportXmrIr,XmrVsBeast,
 }
 
+impl NodeEnum {
+	fn get_index(&self) -> usize {
+		match self {
+			C3pool         => 0,
+			Cake           => 1,
+			CakeEu         => 2,
+			CakeUk         => 3,
+			CakeUs         => 4,
+			Feather1       => 5,
+			Feather2       => 6,
+			MajesticBankIs => 7,
+			MajesticBankSu => 8,
+			Monerujo       => 9,
+			Plowsof1       => 10,
+			Plowsof2       => 11,
+			Rino           => 12,
+			Seth           => 13,
+			SupportXmr     => 14,
+			SupportXmrIr   => 15,
+			_              => 16,
+		}
+	}
+
+	// Return a random node (that isn't the one already selected).
+	pub fn get_random(&self) -> Self {
+		let index = Self::get_index(self);
+		let mut rand = thread_rng().gen_range(0..COMMUNITY_NODE_LENGTH);
+		while rand == index {
+			rand = thread_rng().gen_range(0..COMMUNITY_NODE_LENGTH);
+		}
+		ip_to_enum(NODE_IPS[rand])
+	}
+
+	// Return the node [-1] of this one (wraps around)
+	pub fn get_last(&self) -> Self {
+		let index = Self::get_index(self);
+		if index == 0 {
+			ip_to_enum(NODE_IPS[COMMUNITY_NODE_LENGTH-1])
+		} else {
+			ip_to_enum(NODE_IPS[index-1])
+		}
+	}
+
+	// Return the node [+1] of this one (wraps around)
+	pub fn get_next(&self) -> Self {
+		let index = Self::get_index(self);
+		if index == COMMUNITY_NODE_LENGTH-1 {
+			ip_to_enum(NODE_IPS[0])
+		} else {
+			ip_to_enum(NODE_IPS[index+1])
+		}
+	}
+
+	// This returns relative to the ping.
+	pub fn get_last_from_ping(&self, nodes: &Vec<NodeData>) -> Self {
+		let mut found = false;
+		let mut last = *self;
+		for data in nodes {
+			if found { return last }
+			if *self == data.id { found = true; } else { last = data.id; }
+		}
+		last
+	}
+
+	pub fn get_next_from_ping(&self, nodes: &Vec<NodeData>) -> Self {
+		let mut found = false;
+		for data in nodes {
+			if found { return data.id }
+			if *self == data.id { found = true; }
+		}
+		*self
+	}
+}
+
 impl std::fmt::Display for NodeEnum {
 	fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
 		write!(f, "{:#?}", self)
@@ -225,6 +302,7 @@ impl Ping {
 					ping.lock().unwrap().msg = msg;
 					ping.lock().unwrap().pinged = true;
 					ping.lock().unwrap().auto_selected = false;
+					ping.lock().unwrap().prog = 100.0;
 				},
 				Err(err) => {
 					error!("Ping ... FAIL ... {}", err);
@@ -260,7 +338,7 @@ impl Ping {
 		let ping = Arc::clone(ping);
 		ping.lock().unwrap().pinging = true;
 		ping.lock().unwrap().prog = 0.0;
-		let percent = (100.0 / ((NODE_IPS.len()) as f32)).floor();
+		let percent = (100.0 / (COMMUNITY_NODE_LENGTH as f32)).floor();
 
 		// Create HTTP client
 		let info = "Creating HTTP Client".to_string();
@@ -271,8 +349,8 @@ impl Ping {
 		// Random User Agent
 		let rand_user_agent = crate::Pkg::get_user_agent();
 		// Handle vector
-		let mut handles = Vec::with_capacity(NODE_IPS.len());
-		let node_vec = Arc::new(Mutex::new(Vec::with_capacity(NODE_IPS.len())));
+		let mut handles = Vec::with_capacity(COMMUNITY_NODE_LENGTH);
+		let node_vec = Arc::new(Mutex::new(Vec::with_capacity(COMMUNITY_NODE_LENGTH)));
 
 		for ip in NODE_IPS {
 			let client = client.clone();
@@ -300,7 +378,6 @@ impl Ping {
 		let mut ping = ping.lock().unwrap();
 			ping.fastest = node_vec[0].id;
 			ping.nodes = node_vec;
-			ping.prog = 100.0;
 			ping.msg = info;
 			drop(ping);
 		Ok(fastest_info)
diff --git a/src/p2pool.rs b/src/p2pool.rs
index b4ccae7..1d91ac9 100644
--- a/src/p2pool.rs
+++ b/src/p2pool.rs
@@ -164,17 +164,40 @@ impl P2pool {
 
 		debug!("P2Pool Tab | Rendering [Select fastest ... Ping] buttons");
 		ui.horizontal(|ui| {
-		let width = (width/2.0)-4.0;
-		// [Select fastest node]
-		if ui.add_sized([width, height], Button::new("Select fastest node")).on_hover_text(P2POOL_SELECT_FASTEST).clicked() && ping.lock().unwrap().pinged {
-  				self.node = ping.lock().unwrap().fastest;
-  			}
-
-		// [Ping Button]
-		ui.set_enabled(!ping.lock().unwrap().pinging);
-		if ui.add_sized([width, height], Button::new("Ping community nodes")).on_hover_text(P2POOL_PING).clicked() {
-			Ping::spawn_thread(ping);
-		}});
+			let width = (width/5.0)-6.0;
+			// [Select random node]
+			if ui.add_sized([width, height], Button::new("Select random node")).on_hover_text(P2POOL_SELECT_RANDOM).clicked() {
+				self.node = NodeEnum::get_random(&self.node);
+			}
+			// [Select fastest node]
+			if ui.add_sized([width, height], Button::new("Select fastest node")).on_hover_text(P2POOL_SELECT_FASTEST).clicked() && ping.lock().unwrap().pinged {
+				self.node = ping.lock().unwrap().fastest;
+			}
+			// [Ping Button]
+			ui.add_enabled_ui(!ping.lock().unwrap().pinging, |ui| {
+				if ui.add_sized([width, height], Button::new("Ping community nodes")).on_hover_text(P2POOL_PING).clicked() {
+					Ping::spawn_thread(ping);
+				}
+			});
+			// [Last <-]
+			if ui.add_sized([width, height], Button::new("⬅ Last")).on_hover_text(P2POOL_SELECT_LAST).clicked() {
+				let ping = ping.lock().unwrap();
+				match ping.pinged {
+					true  => self.node = NodeEnum::get_last_from_ping(&self.node, &ping.nodes),
+					false => self.node = NodeEnum::get_last(&self.node),
+				}
+				drop(ping);
+			}
+			// [Next ->]
+			if ui.add_sized([width, height], Button::new("Next ➡")).on_hover_text(P2POOL_SELECT_NEXT).clicked() {
+				let ping = ping.lock().unwrap();
+				match ping.pinged {
+					true  => self.node = NodeEnum::get_next_from_ping(&self.node, &ping.nodes),
+					false => self.node = NodeEnum::get_next(&self.node),
+				}
+				drop(ping);
+			}
+		});
 
 		ui.vertical(|ui| {
 			let height = height / 2.0;