Skip to content

Commit

Permalink
gui(intsaller): ping electrum backend both with tcp & ssl
Browse files Browse the repository at this point in the history
  • Loading branch information
pythcoiner committed Sep 8, 2024
1 parent b9aaea1 commit 53170ef
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 15 deletions.
19 changes: 18 additions & 1 deletion gui/src/installer/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,27 @@ pub enum DefineNode {
NodeTypeSelected(NodeType),
DefineBitcoind(DefineBitcoind),
DefineElectrum(DefineElectrum),
PingResult((NodeType, Result<(), Error>)),
PingResult((PingType, Result<(), Error>)),
Ping,
}

#[derive(Debug, Clone)]
pub enum PingType {
Bitcoind,
ElectrumTcp,
ElectrumSsl,
}

impl PingType {
pub fn node_type(&self) -> NodeType {
match &self {
PingType::Bitcoind => NodeType::Bitcoind,
PingType::ElectrumTcp => NodeType::Electrum,
PingType::ElectrumSsl => NodeType::Electrum,
}
}
}

#[derive(Debug, Clone)]
pub enum SelectBitcoindTypeMsg {
UseExternal(bool),
Expand Down
26 changes: 24 additions & 2 deletions gui/src/installer/step/node/electrum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ impl DefineElectrum {
false
}

pub fn view(&self) -> Element<Message> {
view::define_electrum(&self.address)
pub fn view(&self, is_running: bool) -> Element<Message> {
view::define_electrum(&self.address, is_running)
}

pub fn ping(&self) -> Result<(), Error> {
Expand All @@ -83,4 +83,26 @@ impl DefineElectrum {
.map_err(|e| Error::Electrum(e.to_string()))?;
Ok(())
}

pub fn is_ssl(&self) -> bool {
self.address.value.starts_with("ssl://")
}

pub fn force_ssl(mut self) -> Self {
if self.address.value.starts_with("tcp://") {
self.address.value = self.address.value.replacen("tcp://", "ssl://", 1);
} else if !self.address.value.starts_with("ssl://") {
self.address.value = format!("ssl://{}", self.address.value);
}
self
}

pub fn force_tcp(mut self) -> Self {
if self.address.value.starts_with("ssl://") {
self.address.value = self.address.value.replacen("ssl://", "tcp://", 1);
} else if !self.address.value.starts_with("tcp://") {
self.address.value = format!("tcp://{}", self.address.value);
}
self
}
}
114 changes: 103 additions & 11 deletions gui/src/installer/step/node/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
hw::HardwareWallets,
installer::{
context::Context,
message::{self, Message},
message::{self, Message, PingType},
step::{
node::{bitcoind::DefineBitcoind, electrum::DefineElectrum},
Step,
Expand Down Expand Up @@ -69,10 +69,10 @@ impl NodeDefinition {
}
}

fn view(&self) -> Element<Message> {
fn view(&self, is_running: bool) -> Element<Message> {
match self {
NodeDefinition::Bitcoind(def) => def.view(),
NodeDefinition::Electrum(def) => def.view(),
NodeDefinition::Electrum(def) => def.view(is_running),
}
}

Expand All @@ -88,6 +88,9 @@ pub struct Node {
definition: NodeDefinition,
is_running: Option<Result<(), Error>>,
waiting_for_ping_result: bool,
ssl_ping_result: Option<Result<(), Error>>,
tcp_ping_result: Option<Result<(), Error>>,
original_ssl: bool,
}

impl Node {
Expand All @@ -96,6 +99,17 @@ impl Node {
definition: NodeDefinition::new(node_type),
is_running: None,
waiting_for_ping_result: false,
ssl_ping_result: None,
tcp_ping_result: None,
original_ssl: false,
}
}

fn is_ssl(&self) -> bool {
if let NodeDefinition::Electrum(def) = &self.definition {
def.is_ssl()
} else {
false
}
}
}
Expand Down Expand Up @@ -198,19 +212,91 @@ impl Step for DefineNode {
selected.is_running = None;
let def = selected.definition.clone();
let node_type = def.node_type();
return Command::perform(async move { def.ping() }, move |res| {
Message::DefineNode(message::DefineNode::PingResult((node_type, res)))
});
match node_type {
NodeType::Bitcoind => {
return Command::perform(async move { def.ping() }, move |res| {
Message::DefineNode(message::DefineNode::PingResult((
PingType::Bitcoind,
res,
)))
});
}
// In order to handle user forgetting to specify address prefix, we
// ping both w/ tcp & ssl and update w/ correct value (prefix added if
// missing). Note: we always display a warning if the address is not
// ssl in order to not silently switch to tcp if the user intend
// connect to a ssl server & the server is misconfigured.
NodeType::Electrum => {
selected.tcp_ping_result = None;
selected.ssl_ping_result = None;
selected.original_ssl = selected.is_ssl();

let mut batch = Vec::new();
if let NodeDefinition::Electrum(def) = def {
let ssl = def.clone().force_ssl();
let tcp = def.force_tcp();
let ssl_cmd =
Command::perform(async move { ssl.ping() }, move |res| {
Message::DefineNode(message::DefineNode::PingResult((
PingType::ElectrumSsl,
res,
)))
});
let tcp_cmd =
Command::perform(async move { tcp.ping() }, move |res| {
Message::DefineNode(message::DefineNode::PingResult((
PingType::ElectrumTcp,
res,
)))
});
batch.push(ssl_cmd);
batch.push(tcp_cmd);
}
return Command::batch(batch);
}
}
}
}
message::DefineNode::PingResult((node_type, res)) => {
message::DefineNode::PingResult((ping_type, res)) => {
// Result may not be for the selected node type.
if let Some(node) = self.get_mut(node_type) {
if let Some(node) = self.get_mut(ping_type.node_type()) {
// Make sure we're expecting the ping result. Otherwise, the user may have changed values
// and so the ping result may not apply to the current values.
if node.waiting_for_ping_result {
node.waiting_for_ping_result = false;
node.is_running = Some(res);
match ping_type {
PingType::Bitcoind => {
node.waiting_for_ping_result = false;
node.is_running = Some(res);
}
ping_type => {
if let PingType::ElectrumTcp = ping_type {
node.tcp_ping_result = Some(res);
} else {
node.ssl_ping_result = Some(res);
}
// we wait receiving both ping before decide using tcp or
// ssl
if let (Some(ssl), Some(tcp)) =
(&node.ssl_ping_result, &node.tcp_ping_result)
{
node.waiting_for_ping_result = false;
if let NodeDefinition::Electrum(def) = &mut node.definition
{
if ssl.is_ok() {
*def = def.clone().force_ssl();
} else if tcp.is_ok() {
*def = def.clone().force_tcp();
}
}

node.is_running = if node.original_ssl || ssl.is_ok() {
node.ssl_ping_result.clone()
} else {
node.tcp_ping_result.clone()
};
}
}
}
}
}
}
Expand Down Expand Up @@ -240,7 +326,13 @@ impl Step for DefineNode {
progress,
self.nodes.iter().map(|node| node.definition.node_type()),
self.selected_node_type,
self.selected().definition.view(),
self.selected()
.definition
.view(if let Some(r) = self.selected().is_running.as_ref() {
r.is_ok()
} else {
false
}),
self.selected().is_running.as_ref(),
self.selected().definition.can_try_ping(),
self.selected().waiting_for_ping_result,
Expand Down
15 changes: 14 additions & 1 deletion gui/src/installer/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1370,7 +1370,10 @@ pub fn define_bitcoind<'a>(
.into()
}

pub fn define_electrum<'a>(address: &form::Value<String>) -> Element<'a, Message> {
pub fn define_electrum<'a>(
address: &form::Value<String>,
is_running: bool,
) -> Element<'a, Message> {
let col_address = Column::new()
.push(text("Address:").bold())
.push(
Expand All @@ -1386,6 +1389,16 @@ pub fn define_electrum<'a>(address: &form::Value<String>) -> Element<'a, Message
.size(text::P1_SIZE)
.padding(10),
)
.push_maybe(
if is_running && address.valid && !address.value.starts_with("ssl://") {
Some(
text::caption("Warning, you're going to use a non SSL connection!")
.style(color::RED),
)
} else {
None
},
)
.spacing(10);

Column::new().push(col_address).spacing(50).into()
Expand Down

0 comments on commit 53170ef

Please sign in to comment.