Refactoring the whole channel based structure to a imperative approach
This commit is contained in:
parent
da9daa9359
commit
407085c78b
3141
node/Cargo.lock
generated
3141
node/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -20,18 +20,12 @@ once_cell = "1.21.3"
|
|||||||
async-trait = "0.1.89"
|
async-trait = "0.1.89"
|
||||||
anyhow = "1.0.99"
|
anyhow = "1.0.99"
|
||||||
memory-stats = "1.2.0"
|
memory-stats = "1.2.0"
|
||||||
# jemalloc = "0.3.0"
|
|
||||||
# jemallocator = "0.5.4"
|
|
||||||
textwrap = "0.16.2"
|
textwrap = "0.16.2"
|
||||||
sled = "0.34.7"
|
sled = "0.34.7"
|
||||||
bincode = { version = "2.0.1", features = ["derive", "serde"] }
|
bincode = { version = "2.0.1", features = ["derive", "serde"] }
|
||||||
futures = "0.3.31"
|
futures = "0.3.31"
|
||||||
secp256k1 = { version = "0.31.1", features = ["hashes", "rand", "recovery", "serde"] }
|
|
||||||
ring = "0.17.14"
|
|
||||||
shared = { path = "../shared", features = ["node"] }
|
shared = { path = "../shared", features = ["node"] }
|
||||||
watchlet = { path = "../watchlet" }
|
watchlet = { path = "../watchlet" }
|
||||||
cli-renderer = { path = "../cli-renderer" }
|
cli-renderer = { path = "../cli-renderer" }
|
||||||
tiny_http = "0.12.0"
|
tiny_http = "0.12.0"
|
||||||
serde-big-array = "0.5.1"
|
serde-big-array = "0.5.1"
|
||||||
rust-ipfs = "0.14.1"
|
|
||||||
libp2p = "0.56.0"
|
|
||||||
|
|||||||
@ -3,19 +3,19 @@ use std::sync::Arc;
|
|||||||
use tokio::sync::broadcast;
|
use tokio::sync::broadcast;
|
||||||
|
|
||||||
use super::event_bus::EventBus;
|
use super::event_bus::EventBus;
|
||||||
use crate::executor::ExecutorCommand;
|
use crate::watcher::WatcherCommand;
|
||||||
|
|
||||||
pub enum ErrorEvent {
|
pub enum ErrorEvent {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static ERROR_BUS: Lazy<Arc<EventBus<ExecutorCommand>>> =
|
static ERROR_BUS: Lazy<Arc<EventBus<WatcherCommand>>> =
|
||||||
Lazy::new(|| Arc::new(EventBus::new()));
|
Lazy::new(|| Arc::new(EventBus::new()));
|
||||||
|
|
||||||
pub fn publish_error(event: ExecutorCommand) {
|
pub fn publish_error(event: WatcherCommand) {
|
||||||
ERROR_BUS.publish(event);
|
ERROR_BUS.publish(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn subscribe_error_bus() -> broadcast::Receiver<ExecutorCommand> {
|
pub fn subscribe_error_bus() -> broadcast::Receiver<WatcherCommand> {
|
||||||
ERROR_BUS.subscribe()
|
ERROR_BUS.subscribe()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,17 +0,0 @@
|
|||||||
use once_cell::sync::Lazy;
|
|
||||||
use std::sync::Arc;
|
|
||||||
use tokio::sync::broadcast;
|
|
||||||
|
|
||||||
use super::event_bus::EventBus;
|
|
||||||
use crate::executor::ExecutorCommand;
|
|
||||||
|
|
||||||
static EXECUTOR_EVENT_BUS: Lazy<Arc<EventBus<ExecutorCommand>>> =
|
|
||||||
Lazy::new(|| Arc::new(EventBus::new()));
|
|
||||||
|
|
||||||
pub fn publish_executor_event(event: ExecutorCommand) {
|
|
||||||
EXECUTOR_EVENT_BUS.publish(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn subscribe_executor_event() -> broadcast::Receiver<ExecutorCommand> {
|
|
||||||
EXECUTOR_EVENT_BUS.subscribe()
|
|
||||||
}
|
|
||||||
@ -2,7 +2,7 @@ use crate::args::*;
|
|||||||
use crate::network::NodeId;
|
use crate::network::NodeId;
|
||||||
use shared::blockchain_core::ChainData;
|
use shared::blockchain_core::ChainData;
|
||||||
use vlogger::*;
|
use vlogger::*;
|
||||||
use crate::executor::ExecutorCommand;
|
use crate::watcher::WatcherCommand;
|
||||||
use crate::node::*;
|
use crate::node::*;
|
||||||
use crate::log;
|
use crate::log;
|
||||||
use cli_renderer::RenderCommand;
|
use cli_renderer::RenderCommand;
|
||||||
@ -46,18 +46,18 @@ fn handle_ping(cmd: CliPingCommand) -> NodeCommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cli(input: &str) -> ExecutorCommand {
|
pub fn cli(input: &str) -> WatcherCommand {
|
||||||
let argv: Vec<&str> = std::iter::once(" ")
|
let argv: Vec<&str> = std::iter::once(" ")
|
||||||
.chain(input.split_whitespace())
|
.chain(input.split_whitespace())
|
||||||
.collect();
|
.collect();
|
||||||
match Cli::try_parse_from(argv) {
|
match Cli::try_parse_from(argv) {
|
||||||
Ok(cmd) => match cmd.command {
|
Ok(cmd) => match cmd.command {
|
||||||
CliCommand::Layout { mode } => ExecutorCommand::Render(RenderCommand::ChangeLayout(mode)),
|
CliCommand::Layout { mode } => WatcherCommand::Render(RenderCommand::ChangeLayout(mode)),
|
||||||
CliCommand::Clear => ExecutorCommand::Render(RenderCommand::ClearPane),
|
CliCommand::Clear => WatcherCommand::Render(RenderCommand::ClearPane),
|
||||||
CliCommand::Peer { peer_cmd } => ExecutorCommand::Node(handle_peer_command(peer_cmd)),
|
CliCommand::Peer { peer_cmd } => WatcherCommand::Node(handle_peer_command(peer_cmd)),
|
||||||
CliCommand::Block { block_cmd } => ExecutorCommand::Node(handle_block_command(block_cmd)),
|
CliCommand::Block { block_cmd } => WatcherCommand::Node(handle_block_command(block_cmd)),
|
||||||
CliCommand::Transaction(tx) => {
|
CliCommand::Transaction(tx) => {
|
||||||
ExecutorCommand::Node(NodeCommand::ProcessChainData(ChainData::NodeTransaction(tx)))
|
WatcherCommand::Node(NodeCommand::ProcessChainData(ChainData::NodeTransaction(tx)))
|
||||||
}
|
}
|
||||||
CliCommand::Award { address, amount } => {
|
CliCommand::Award { address, amount } => {
|
||||||
let mut bytes = [0u8; 20];
|
let mut bytes = [0u8; 20];
|
||||||
@ -68,15 +68,15 @@ pub fn cli(input: &str) -> ExecutorCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bytes.copy_from_slice(address.as_bytes());
|
bytes.copy_from_slice(address.as_bytes());
|
||||||
ExecutorCommand::Node(NodeCommand::AwardCurrency{ address: bytes, amount }
|
WatcherCommand::Node(NodeCommand::AwardCurrency{ address: bytes, amount }
|
||||||
)}
|
)}
|
||||||
CliCommand::DebugShowId => ExecutorCommand::Node(NodeCommand::ShowId),
|
CliCommand::DebugShowId => WatcherCommand::Node(NodeCommand::ShowId),
|
||||||
CliCommand::StartListner { addr } => {
|
CliCommand::StartListner { addr } => {
|
||||||
ExecutorCommand::Node(NodeCommand::StartListner(addr.parse().unwrap()))
|
WatcherCommand::Node(NodeCommand::StartListner(addr.parse().unwrap()))
|
||||||
}
|
}
|
||||||
CliCommand::Seeds { seed_cmd } => ExecutorCommand::Node(handle_seed_command(seed_cmd)),
|
CliCommand::Seeds { seed_cmd } => WatcherCommand::Node(handle_seed_command(seed_cmd)),
|
||||||
CliCommand::Ping { ping_cmd } => ExecutorCommand::Node(handle_ping(ping_cmd)),
|
CliCommand::Ping { ping_cmd } => WatcherCommand::Node(handle_ping(ping_cmd)),
|
||||||
},
|
},
|
||||||
Err(e) => ExecutorCommand::InvalidCommand(format!("{e}")),
|
Err(e) => WatcherCommand::InvalidCommand(format!("{e}")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,15 +0,0 @@
|
|||||||
use crate::node::NodeCommand;
|
|
||||||
use cli_renderer::RenderCommand;
|
|
||||||
use crate::watcher::WatcherCommand;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub enum ExecutorCommand {
|
|
||||||
NodeResponse(String),
|
|
||||||
Echo(Vec<String>),
|
|
||||||
Print(String),
|
|
||||||
InvalidCommand(String),
|
|
||||||
Node(NodeCommand),
|
|
||||||
Render(RenderCommand),
|
|
||||||
Watcher(WatcherCommand),
|
|
||||||
Exit,
|
|
||||||
}
|
|
||||||
@ -1,106 +0,0 @@
|
|||||||
use crate::{
|
|
||||||
bus::{publish_system_event, publish_watcher_event, subscribe_system_event, SystemEvent},
|
|
||||||
log,
|
|
||||||
node::NodeCommand,
|
|
||||||
watcher::WatcherCommand,
|
|
||||||
};
|
|
||||||
|
|
||||||
use cli_renderer::pane::RenderTarget;
|
|
||||||
use thiserror::Error;
|
|
||||||
use tokio::{select, sync::mpsc};
|
|
||||||
use vlogger::*;
|
|
||||||
|
|
||||||
use super::ExecutorCommand;
|
|
||||||
use crate::RenderCommand;
|
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
|
||||||
pub enum InProcessError {
|
|
||||||
#[error("TODO: {0}")]
|
|
||||||
TODO(String),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Executor {
|
|
||||||
node_tx: mpsc::Sender<NodeCommand>,
|
|
||||||
rx: mpsc::Receiver<ExecutorCommand>,
|
|
||||||
exit: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Executor {
|
|
||||||
pub fn new(node_tx: mpsc::Sender<NodeCommand>, rx: mpsc::Receiver<ExecutorCommand>) -> Self {
|
|
||||||
Self {
|
|
||||||
node_tx,
|
|
||||||
rx,
|
|
||||||
exit: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn run(&mut self) {
|
|
||||||
publish_system_event(SystemEvent::ExecutorStarted);
|
|
||||||
let mut sys_rx = subscribe_system_event();
|
|
||||||
while !self.exit {
|
|
||||||
select! {
|
|
||||||
_ = self.listen() => {}
|
|
||||||
event_res = sys_rx.recv() => {
|
|
||||||
if let Ok(event) = event_res {
|
|
||||||
match event {
|
|
||||||
SystemEvent::Shutdown => {
|
|
||||||
self.exit().await;
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn exit(&mut self) {
|
|
||||||
log(msg!(DEBUG, "Executor Exit"));
|
|
||||||
self.exit = true
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn listen(&mut self) {
|
|
||||||
if let Some(cmd) = self.rx.recv().await {
|
|
||||||
let _ = self.execute(cmd).await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn send_node_cmd(&self, cmd: NodeCommand) {
|
|
||||||
self.node_tx.send(cmd).await.unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn handle_node_cmd(&self, cmd: NodeCommand) {
|
|
||||||
self.send_node_cmd(cmd).await;
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn echo(&self, s: Vec<String>) {
|
|
||||||
let mut str = s.join(" ");
|
|
||||||
str.push_str("\n");
|
|
||||||
let rd_cmd = WatcherCommand::Render(RenderCommand::StringToPaneId {
|
|
||||||
str,
|
|
||||||
pane: RenderTarget::CliOutput,
|
|
||||||
});
|
|
||||||
publish_watcher_event(rd_cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn invalid_command(&self, str: String) {
|
|
||||||
let rd_cmd = WatcherCommand::Render(RenderCommand::StringToPaneId {
|
|
||||||
str,
|
|
||||||
pane: RenderTarget::CliOutput,
|
|
||||||
});
|
|
||||||
publish_watcher_event(rd_cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn execute(&mut self, cmd: ExecutorCommand) {
|
|
||||||
match cmd {
|
|
||||||
ExecutorCommand::NodeResponse(resp) => log(resp),
|
|
||||||
ExecutorCommand::Node(n) => self.handle_node_cmd(n).await,
|
|
||||||
ExecutorCommand::Render(p) => publish_watcher_event(WatcherCommand::Render(p)),
|
|
||||||
ExecutorCommand::Watcher(w) => publish_watcher_event(w),
|
|
||||||
ExecutorCommand::Echo(s) => self.echo(s).await,
|
|
||||||
ExecutorCommand::Print(s) => log(s),
|
|
||||||
ExecutorCommand::InvalidCommand(str) => self.invalid_command(str).await,
|
|
||||||
ExecutorCommand::Exit => self.exit().await,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -41,20 +41,11 @@ pub mod bus {
|
|||||||
pub mod system;
|
pub mod system;
|
||||||
|
|
||||||
pub use error::*;
|
pub use error::*;
|
||||||
pub mod executor;
|
|
||||||
pub use network::*;
|
pub use network::*;
|
||||||
pub use watcher::*;
|
pub use watcher::*;
|
||||||
pub use system::*;
|
pub use system::*;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod executor {
|
|
||||||
pub mod executor;
|
|
||||||
pub use executor::*;
|
|
||||||
|
|
||||||
pub mod command;
|
|
||||||
pub use command::*;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub mod watcher {
|
pub mod watcher {
|
||||||
pub mod builder;
|
pub mod builder;
|
||||||
pub mod watcher;
|
pub mod watcher;
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
use crate::executor::ExecutorCommand;
|
use crate::{log, watcher};
|
||||||
use crate::log;
|
|
||||||
use crate::network::NodeId;
|
use crate::network::NodeId;
|
||||||
use crate::node::node;
|
use crate::node::node;
|
||||||
use super::ProtocolMessage;
|
use super::ProtocolMessage;
|
||||||
@ -16,7 +15,6 @@ pub struct Connection {
|
|||||||
node_id: NodeId,
|
node_id: NodeId,
|
||||||
peer_id: NodeId,
|
peer_id: NodeId,
|
||||||
stream: net::TcpStream,
|
stream: net::TcpStream,
|
||||||
exec_tx: mpsc::Sender<ExecutorCommand>,
|
|
||||||
rx: mpsc::Receiver<ProtocolMessage>,
|
rx: mpsc::Receiver<ProtocolMessage>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,7 +23,6 @@ impl Connection {
|
|||||||
node_id: NodeId,
|
node_id: NodeId,
|
||||||
peer_id: NodeId,
|
peer_id: NodeId,
|
||||||
stream: net::TcpStream,
|
stream: net::TcpStream,
|
||||||
exec_tx: mpsc::Sender<ExecutorCommand>,
|
|
||||||
rx: mpsc::Receiver<ProtocolMessage>,
|
rx: mpsc::Receiver<ProtocolMessage>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@ -33,12 +30,10 @@ impl Connection {
|
|||||||
peer_id,
|
peer_id,
|
||||||
stream,
|
stream,
|
||||||
rx,
|
rx,
|
||||||
exec_tx,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn start(mut self) {
|
pub async fn poll(mut self) {
|
||||||
tokio::spawn(async move {
|
|
||||||
log(msg!(DEBUG, "Started Message Handler for {}", self.peer_id));
|
log(msg!(DEBUG, "Started Message Handler for {}", self.peer_id));
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
@ -61,30 +56,18 @@ impl Connection {
|
|||||||
message_result = Connector::receive_message(&mut self.stream) => {
|
message_result = Connector::receive_message(&mut self.stream) => {
|
||||||
match message_result {
|
match message_result {
|
||||||
Ok(message) => {
|
Ok(message) => {
|
||||||
log(msg!(DEBUG, "Received Message from {}", self.peer_id));
|
todo!("[TODO] Return parsed command to propagate");
|
||||||
|
|
||||||
let command = ExecutorCommand::Node(node::NodeCommand::ProcessMessage {
|
|
||||||
peer_id: self.peer_id.clone(),
|
|
||||||
message: message.clone()
|
|
||||||
});
|
|
||||||
|
|
||||||
if self.exec_tx.send(command).await.is_err() {
|
|
||||||
log(msg!(ERROR, "Failed to send command to main thread from {}", self.peer_id));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log(msg!(WARNING, "Connection to {} closed: {}", self.peer_id, e));
|
log(msg!(WARNING, "Connection to {} closed: {}", self.peer_id, e));
|
||||||
let cmd = ExecutorCommand::Node(node::NodeCommand::RemovePeer {
|
let cmd = watcher::WatcherCommand::Node(node::NodeCommand::RemovePeer {
|
||||||
peer_id: self.peer_id
|
peer_id: self.peer_id
|
||||||
});
|
});
|
||||||
self.exec_tx.send(cmd).await.unwrap();
|
todo!("[TODO] Return Error Node Command to propagate");
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,7 +12,6 @@ use crate::log;
|
|||||||
use crate::network::NodeId;
|
use crate::network::NodeId;
|
||||||
use super::Connection;
|
use super::Connection;
|
||||||
use crate::bus::*;
|
use crate::bus::*;
|
||||||
use crate::executor::ExecutorCommand;
|
|
||||||
use crate::node::node;
|
use crate::node::node;
|
||||||
use crate::node::{NetworkError, error};
|
use crate::node::{NetworkError, error};
|
||||||
use super::ProtocolMessage;
|
use super::ProtocolMessage;
|
||||||
@ -26,8 +25,8 @@ pub enum ConnectorCommand {
|
|||||||
pub struct Connector {
|
pub struct Connector {
|
||||||
node_id: NodeId,
|
node_id: NodeId,
|
||||||
addr: SocketAddr,
|
addr: SocketAddr,
|
||||||
exec_tx: mpsc::Sender<ExecutorCommand>,
|
connections: Vec<Connection>,
|
||||||
rx: mpsc::Receiver<ConnectorCommand>,
|
listener: Option<tokio::net::TcpListener>,
|
||||||
exit: bool,
|
exit: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,147 +42,134 @@ impl Connector {
|
|||||||
pub fn new(
|
pub fn new(
|
||||||
node_id: NodeId,
|
node_id: NodeId,
|
||||||
addr: SocketAddr,
|
addr: SocketAddr,
|
||||||
exec_tx: mpsc::Sender<ExecutorCommand>,
|
|
||||||
rx: mpsc::Receiver<ConnectorCommand>,
|
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
node_id,
|
node_id,
|
||||||
addr,
|
addr,
|
||||||
exec_tx,
|
connections: Vec::new(),
|
||||||
rx,
|
listener: None,
|
||||||
exit: false,
|
exit: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn start(&mut self) {
|
pub async fn init(&mut self) {
|
||||||
let mut listner: Option<tokio::net::TcpListener> = None;
|
|
||||||
let mut listner_err = None;
|
|
||||||
for _ in 0..MAX_LISTNER_TRIES {
|
for _ in 0..MAX_LISTNER_TRIES {
|
||||||
match tokio::net::TcpListener::bind(self.addr).await {
|
match tokio::net::TcpListener::bind(self.addr).await {
|
||||||
Ok(l) => {
|
Ok(l) => {
|
||||||
log(msg!(DEBUG, "Listening on address: {}", self.addr));
|
log(msg!(DEBUG, "Listening on address: {}", self.addr));
|
||||||
listner = Some(l);
|
self.listener = Some(l);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
self.addr.set_port(self.addr.port() + 1);
|
self.addr.set_port(self.addr.port() + 1);
|
||||||
listner_err = Some(e);
|
let listner_err = Some(e);
|
||||||
|
println!("{:#?}", listner_err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if let Some(listener) = listner {
|
}
|
||||||
while !self.exit {
|
|
||||||
|
pub async fn poll(&mut self) -> Result<Option<node::NodeCommand>, ConnectorError> {
|
||||||
|
if let Some(listener) = &mut self.listener {
|
||||||
|
todo!("Implement Vec Poll for connections");
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
cmd_result = self.rx.recv() => {
|
// cmd_result = self.rx.recv() => {
|
||||||
match cmd_result {
|
// todo!("Implement Vec Poll for connections");
|
||||||
Some(cmd) => {
|
// match cmd_result {
|
||||||
self.execute_cmd(cmd).await;
|
// Some(cmd) => {
|
||||||
}
|
// self.execute_cmd(cmd).await
|
||||||
None => {
|
// }
|
||||||
log(msg!(DEBUG, "Command channel closed"));
|
// None => {
|
||||||
break;
|
// log(msg!(DEBUG, "Command channel closed"));
|
||||||
}
|
// todo!("Handle Connector Error");
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
accept_result = listener.accept() => {
|
accept_result = listener.accept() => {
|
||||||
match accept_result {
|
match accept_result {
|
||||||
Ok((stream, addr)) => {
|
Ok((stream, addr)) => {
|
||||||
log(msg!(DEBUG, "Accepted connection from {}", addr));
|
log(msg!(DEBUG, "Accepted connection from {}", addr));
|
||||||
self.establish_connection_inbound(stream, addr).await;
|
let peer = self.establish_connection_inbound(stream, addr).await?;
|
||||||
|
Ok(Some(node::NodeCommand::AddPeer(peer)))
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log(msg!(ERROR, "Failed to accept connection: {}", e));
|
log(msg!(ERROR, "Failed to accept connection: {}", e));
|
||||||
|
todo!("Implement Connector TcpListner connection fail");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
log(msg!(
|
log(msg!(
|
||||||
FATAL,
|
FATAL,
|
||||||
"Failed to start TCP Listener: {}",
|
"Failed to start TCP Listener",
|
||||||
listner_err.unwrap()
|
|
||||||
));
|
));
|
||||||
|
todo!("Implement Connector TcpListner fail");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn execute_cmd(&mut self, cmd: ConnectorCommand) {
|
pub async fn execute_cmd(&mut self, cmd: ConnectorCommand) -> Result<Option<node::NodeCommand>, ConnectorError> {
|
||||||
match cmd {
|
match cmd {
|
||||||
ConnectorCommand::ConnectToTcpPeer(addr) => self.connect_to_peer(addr).await,
|
ConnectorCommand::ConnectToTcpPeer(addr) => {
|
||||||
|
let peer = self.connect_to_peer(addr).await?;
|
||||||
|
Ok(Some(node::NodeCommand::AddPeer(peer)))
|
||||||
|
},
|
||||||
ConnectorCommand::ConnectToTcpSeed(addr) => {
|
ConnectorCommand::ConnectToTcpSeed(addr) => {
|
||||||
self.connect_to_seed(addr).await;
|
let peer = self.connect_to_seed(addr).await?;
|
||||||
|
Ok(Some(node::NodeCommand::AddPeer(peer)))
|
||||||
}
|
}
|
||||||
ConnectorCommand::Shutdown => {
|
ConnectorCommand::Shutdown => {
|
||||||
self.exit = true;
|
self.exit = true;
|
||||||
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn connect_to_seed(&self, addr: SocketAddr) {
|
pub async fn connect_to_seed(&mut self, addr: SocketAddr) -> Result<node::TcpPeer, ConnectorError> {
|
||||||
match net::TcpStream::connect(addr)
|
match net::TcpStream::connect(addr)
|
||||||
.await
|
.await
|
||||||
.with_context(|| format!("Connecting to {}", addr))
|
.with_context(|| format!("Connecting to {}", addr))
|
||||||
{
|
{
|
||||||
Ok(stream) => self.establish_connection_to_seed(stream, addr).await,
|
Ok(stream) => {
|
||||||
|
let peer = self.establish_connection_outbound(stream, addr).await;
|
||||||
|
publish_network_event(NetworkEvent::SeedConnected(addr.to_string()));
|
||||||
|
peer
|
||||||
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
// let err = ConnectorError::ConnectionError(e.into());
|
// let err = ConnectorError::ConnectionError(e.into());
|
||||||
print_error_chain(&e.into());
|
print_error_chain(&e.into());
|
||||||
|
todo!("Handle connector error propagation");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn connect_to_peer(&self, addr: SocketAddr) {
|
pub async fn connect_to_peer_inbound(&mut self, addr: SocketAddr) -> Result<node::TcpPeer, ConnectorError> {
|
||||||
|
match net::TcpStream::connect(addr).await {
|
||||||
|
Ok(stream) => self.establish_connection_inbound(stream, addr).await,
|
||||||
|
Err(e) => {
|
||||||
|
let err = ConnectorError::ConnectionError(e.into());
|
||||||
|
print_error_chain(&err.into());
|
||||||
|
todo!("Handle connector error propagation");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn connect_to_peer(&mut self, addr: SocketAddr) -> Result<node::TcpPeer, ConnectorError> {
|
||||||
match net::TcpStream::connect(addr).await {
|
match net::TcpStream::connect(addr).await {
|
||||||
Ok(stream) => self.establish_connection_outbound(stream, addr).await,
|
Ok(stream) => self.establish_connection_outbound(stream, addr).await,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let err = ConnectorError::ConnectionError(e.into());
|
let err = ConnectorError::ConnectionError(e.into());
|
||||||
print_error_chain(&err.into());
|
print_error_chain(&err.into());
|
||||||
|
todo!("Handle connector error propagation");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn establish_connection_to_seed(
|
|
||||||
&self,
|
|
||||||
mut stream: tokio::net::TcpStream,
|
|
||||||
addr: SocketAddr,
|
|
||||||
) {
|
|
||||||
let handshake = ProtocolMessage::Handshake {
|
|
||||||
peer_id: self.node_id.clone(),
|
|
||||||
version: "".to_string(),
|
|
||||||
};
|
|
||||||
match Connector::send_message(&mut stream, &handshake).await {
|
|
||||||
Ok(()) => {
|
|
||||||
if let Ok(mes) = Connector::receive_message(&mut stream).await {
|
|
||||||
let (ch_tx, ch_rx) = mpsc::channel::<ProtocolMessage>(100);
|
|
||||||
let peer = match mes {
|
|
||||||
ProtocolMessage::HandshakeAck { peer_id, .. } => {
|
|
||||||
node::TcpPeer::new(peer_id, addr, ch_tx)
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
log(msg!(
|
|
||||||
ERROR,
|
|
||||||
"Invalid Message On Connetion Establishment: {mes}"
|
|
||||||
));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let cmd = ExecutorCommand::Node(node::NodeCommand::AddPeer(peer.clone()));
|
|
||||||
publish_network_event(NetworkEvent::SeedConnected(addr.to_string()));
|
|
||||||
let _ = self.exec_tx.send(cmd).await;
|
|
||||||
Connection::new(self.node_id.clone(), peer.id, stream, self.exec_tx.clone(), ch_rx)
|
|
||||||
.start()
|
|
||||||
.await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(e) => print_error_chain(&e.into()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn establish_connection_outbound(
|
async fn establish_connection_outbound(
|
||||||
&self,
|
&mut self,
|
||||||
mut stream: tokio::net::TcpStream,
|
mut stream: tokio::net::TcpStream,
|
||||||
addr: SocketAddr,
|
addr: SocketAddr,
|
||||||
) {
|
) -> Result<node::TcpPeer, ConnectorError> {
|
||||||
let handshake = ProtocolMessage::Handshake {
|
let handshake = ProtocolMessage::Handshake {
|
||||||
peer_id: self.node_id.clone(),
|
peer_id: self.node_id.clone(),
|
||||||
version: "".to_string(),
|
version: "".to_string(),
|
||||||
@ -201,25 +187,28 @@ impl Connector {
|
|||||||
ERROR,
|
ERROR,
|
||||||
"Invalid Message On Connetion Establishment: {mes}"
|
"Invalid Message On Connetion Establishment: {mes}"
|
||||||
));
|
));
|
||||||
return;
|
todo!("Handle connector receive message fail");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let cmd = ExecutorCommand::Node(node::NodeCommand::AddPeer(peer.clone()));
|
let connection = Connection::new(self.node_id.clone(), peer.id.clone(), stream, ch_rx);
|
||||||
let _ = self.exec_tx.send(cmd).await;
|
self.connections.push(connection);
|
||||||
Connection::new(self.node_id.clone(), peer.id, stream, self.exec_tx.clone(), ch_rx)
|
Ok(peer)
|
||||||
.start()
|
} else {
|
||||||
.await;
|
todo!("Handle connector receive message fail");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => print_error_chain(&e.into()),
|
Err(e) => {
|
||||||
|
print_error_chain(&e.into());
|
||||||
|
todo!("Handle Connector Error");
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn establish_connection_inbound(
|
async fn establish_connection_inbound(
|
||||||
&self,
|
&mut self,
|
||||||
mut stream: tokio::net::TcpStream,
|
mut stream: tokio::net::TcpStream,
|
||||||
addr: SocketAddr,
|
addr: SocketAddr,
|
||||||
) {
|
) -> Result<node::TcpPeer, ConnectorError> {
|
||||||
if let Ok(mes) = Connector::receive_message(&mut stream).await {
|
if let Ok(mes) = Connector::receive_message(&mut stream).await {
|
||||||
let (ch_tx, ch_rx) = mpsc::channel::<ProtocolMessage>(100);
|
let (ch_tx, ch_rx) = mpsc::channel::<ProtocolMessage>(100);
|
||||||
let peer = match mes {
|
let peer = match mes {
|
||||||
@ -230,7 +219,11 @@ impl Connector {
|
|||||||
};
|
};
|
||||||
match Connector::send_message(&mut stream, &ack).await {
|
match Connector::send_message(&mut stream, &ack).await {
|
||||||
Ok(()) => node::TcpPeer::new(peer_id, addr, ch_tx),
|
Ok(()) => node::TcpPeer::new(peer_id, addr, ch_tx),
|
||||||
Err(e) => return print_error_chain(&e.into()),
|
Err(e) => {
|
||||||
|
print_error_chain(&e.into());
|
||||||
|
todo!("Implement inbound conneciton message send fail")
|
||||||
|
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@ -238,14 +231,14 @@ impl Connector {
|
|||||||
ERROR,
|
ERROR,
|
||||||
"Invalid Message On Connetion Establishment: {mes}"
|
"Invalid Message On Connetion Establishment: {mes}"
|
||||||
));
|
));
|
||||||
return;
|
todo!("Implement inbound conneciton message invalid");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let cmd = ExecutorCommand::Node(node::NodeCommand::AddPeer(peer.clone()));
|
let connection = Connection::new(self.node_id.clone(), peer.id.clone(), stream, ch_rx);
|
||||||
let _ = self.exec_tx.send(cmd).await;
|
self.connections.push(connection);
|
||||||
Connection::new(self.node_id.clone(), peer.id, stream, self.exec_tx.clone(), ch_rx)
|
Ok(peer)
|
||||||
.start()
|
} else {
|
||||||
.await;
|
todo!("Implement inbount connection message read fail");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +0,0 @@
|
|||||||
segment_size: 1048576
|
|
||||||
use_compression: false
|
|
||||||
version: 0.34
|
|
||||||
l–ø
|
|
||||||
Binary file not shown.
@ -1,4 +0,0 @@
|
|||||||
segment_size: 1048576
|
|
||||||
use_compression: false
|
|
||||||
version: 0.34
|
|
||||||
l–ø
|
|
||||||
Binary file not shown.
@ -13,7 +13,7 @@ use shared::ws_protocol::{ WsClientRequest, WsClientResponse };
|
|||||||
use watchlet::WalletError;
|
use watchlet::WalletError;
|
||||||
|
|
||||||
use crate::db::BINCODE_CONFIG;
|
use crate::db::BINCODE_CONFIG;
|
||||||
use crate::executor::ExecutorCommand;
|
use crate::watcher::WatcherCommand;
|
||||||
use crate::log;
|
use crate::log;
|
||||||
use crate::node::NodeCommand;
|
use crate::node::NodeCommand;
|
||||||
use crate::seeds_constants::WS_LISTEN_ADDRESS;
|
use crate::seeds_constants::WS_LISTEN_ADDRESS;
|
||||||
@ -46,13 +46,13 @@ pub enum WsServerError {
|
|||||||
|
|
||||||
pub struct WsServer {
|
pub struct WsServer {
|
||||||
rx: Receiver<WsCommand>,
|
rx: Receiver<WsCommand>,
|
||||||
tx: Sender<ExecutorCommand>,
|
tx: Sender<WatcherCommand>,
|
||||||
clients: HashMap<SocketAddr, Sender<WsClientResponse>>,
|
clients: HashMap<SocketAddr, Sender<WsClientResponse>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_ws_client_request(
|
async fn handle_ws_client_request(
|
||||||
req: WsClientRequest,
|
req: WsClientRequest,
|
||||||
_tx: Sender<ExecutorCommand>,
|
_tx: Sender<WatcherCommand>,
|
||||||
) -> Result<(), WsServerError> {
|
) -> Result<(), WsServerError> {
|
||||||
match req {
|
match req {
|
||||||
WsClientRequest::Ping => {
|
WsClientRequest::Ping => {
|
||||||
@ -61,7 +61,7 @@ async fn handle_ws_client_request(
|
|||||||
}
|
}
|
||||||
WsClientRequest::BroadcastTransaction(sign_tx) => {
|
WsClientRequest::BroadcastTransaction(sign_tx) => {
|
||||||
Validator::verify_signature(&sign_tx)?;
|
Validator::verify_signature(&sign_tx)?;
|
||||||
let _cmd = ExecutorCommand::Node(NodeCommand::BroadcastTransaction(sign_tx));
|
let _cmd = WatcherCommand::Node(NodeCommand::BroadcastTransaction(sign_tx));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -70,7 +70,7 @@ async fn handle_ws_client_request(
|
|||||||
async fn ws_connection(
|
async fn ws_connection(
|
||||||
stream: TcpStream,
|
stream: TcpStream,
|
||||||
mut rx: Receiver<WsClientResponse>,
|
mut rx: Receiver<WsClientResponse>,
|
||||||
_tx: Sender<ExecutorCommand>,
|
_tx: Sender<WatcherCommand>,
|
||||||
) -> Result<(), WsServerError> {
|
) -> Result<(), WsServerError> {
|
||||||
let ws_server = tokio_tungstenite::accept_async(stream).await.unwrap();
|
let ws_server = tokio_tungstenite::accept_async(stream).await.unwrap();
|
||||||
let (mut write, mut read) = ws_server.split();
|
let (mut write, mut read) = ws_server.split();
|
||||||
@ -101,7 +101,7 @@ async fn ws_connection(
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl WsServer {
|
impl WsServer {
|
||||||
pub fn new(rx: Receiver<WsCommand>, tx: Sender<ExecutorCommand>) -> Self {
|
pub fn new(rx: Receiver<WsCommand>, tx: Sender<WatcherCommand>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
rx,
|
rx,
|
||||||
tx,
|
tx,
|
||||||
|
|||||||
@ -1,13 +1,11 @@
|
|||||||
use crate::bus::{publish_system_event, publish_watcher_event, subscribe_system_event, SystemEvent};
|
use crate::bus::{publish_system_event, publish_watcher_event, subscribe_system_event, SystemEvent};
|
||||||
use shared::blockchain_core::{self, ChainData, SignedTransaction, validator::ValidationError};
|
use shared::blockchain_core::{self, ChainData, SignedTransaction, validator::ValidationError};
|
||||||
use crate::print_error_chain;
|
use crate::print_error_chain;
|
||||||
use crate::executor::ExecutorCommand;
|
|
||||||
use crate::log;
|
use crate::log;
|
||||||
use crate::network::{NodeId, ProtocolMessage};
|
use crate::network::{NodeId, ProtocolMessage};
|
||||||
use crate::network::{Connector, ConnectorCommand};
|
use crate::network::{Connector, ConnectorCommand};
|
||||||
use crate::seeds_constants::SEED_NODES;
|
use crate::seeds_constants::SEED_NODES;
|
||||||
use crate::watcher::{WatcherCommand, WatcherMode};
|
use crate::watcher::{WatcherCommand, WatcherMode};
|
||||||
use crate::network::ws_server::{WsCommand, WsServer};
|
|
||||||
use super::{ Blockchain, BlockchainError };
|
use super::{ Blockchain, BlockchainError };
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
@ -15,8 +13,6 @@ use std::net::SocketAddr;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use thiserror::*;
|
use thiserror::*;
|
||||||
use tokio::select;
|
|
||||||
use tokio::sync::mpsc;
|
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use vlogger::*;
|
use vlogger::*;
|
||||||
|
|
||||||
@ -39,15 +35,12 @@ impl TcpPeer {
|
|||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub struct Node {
|
pub struct Node {
|
||||||
pub tcp_connector: Option<mpsc::Sender<ConnectorCommand>>,
|
pub tcp_connector: Option<Connector>,
|
||||||
pub id: NodeId,
|
pub id: NodeId,
|
||||||
pub addr: Option<SocketAddr>,
|
pub addr: Option<SocketAddr>,
|
||||||
pub tcp_peers: HashMap<NodeId, TcpPeer>,
|
pub tcp_peers: HashMap<NodeId, TcpPeer>,
|
||||||
chain: Blockchain,
|
chain: Blockchain,
|
||||||
listner_handle: Option<tokio::task::JoinHandle<()>>,
|
listner_handle: Option<tokio::task::JoinHandle<()>>,
|
||||||
exec_tx: mpsc::Sender<ExecutorCommand>,
|
|
||||||
rx: mpsc::Receiver<NodeCommand>,
|
|
||||||
tx: mpsc::Sender<NodeCommand>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
@ -123,49 +116,35 @@ impl Node {
|
|||||||
|
|
||||||
pub async fn new_with_id(
|
pub async fn new_with_id(
|
||||||
id: NodeId,
|
id: NodeId,
|
||||||
exec_tx: mpsc::Sender<ExecutorCommand>,
|
|
||||||
addr: Option<SocketAddr>,
|
addr: Option<SocketAddr>,
|
||||||
chain: Blockchain,
|
chain: Blockchain,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let (tx, rx) = mpsc::channel::<NodeCommand>(100);
|
|
||||||
Self {
|
Self {
|
||||||
id,
|
id,
|
||||||
tcp_peers: HashMap::new(),
|
tcp_peers: HashMap::new(),
|
||||||
addr,
|
addr,
|
||||||
exec_tx,
|
|
||||||
chain,
|
chain,
|
||||||
listner_handle: None,
|
listner_handle: None,
|
||||||
tcp_connector: None,
|
tcp_connector: None,
|
||||||
tx,
|
|
||||||
rx,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(
|
pub fn new(
|
||||||
addr: Option<SocketAddr>,
|
addr: Option<SocketAddr>,
|
||||||
exec_tx: mpsc::Sender<ExecutorCommand>,
|
|
||||||
chain: Blockchain,
|
chain: Blockchain,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let (tx, rx) = mpsc::channel::<NodeCommand>(100);
|
|
||||||
Self {
|
Self {
|
||||||
id: NodeId(*Uuid::new_v4().as_bytes()),
|
id: NodeId(*Uuid::new_v4().as_bytes()),
|
||||||
tcp_peers: HashMap::new(),
|
tcp_peers: HashMap::new(),
|
||||||
addr,
|
addr,
|
||||||
exec_tx,
|
|
||||||
listner_handle: None,
|
listner_handle: None,
|
||||||
tcp_connector: None,
|
tcp_connector: None,
|
||||||
chain,
|
chain,
|
||||||
tx,
|
|
||||||
rx,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn shutdown(&mut self) {
|
async fn shutdown(&mut self) {
|
||||||
if let Some(conn) = &self.tcp_connector {
|
if let Some(conn) = &self.tcp_connector {
|
||||||
let res = conn.send(ConnectorCommand::Shutdown).await;
|
|
||||||
if res.is_err() {
|
|
||||||
log(msg!(ERROR, "Failed to send shutdown signal to connector"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
let _ = self.chain.shutdown().await;
|
let _ = self.chain.shutdown().await;
|
||||||
}
|
}
|
||||||
@ -300,35 +279,22 @@ impl Node {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tx(&self) -> mpsc::Sender<NodeCommand> {
|
async fn connector_cmd(&mut self, cmd: ConnectorCommand) -> Result<Option<NodeCommand>, crate::network::ConnectorError> {
|
||||||
return self.tx.clone();
|
match &mut self.tcp_connector {
|
||||||
}
|
Some(t) => { t.execute_cmd(cmd).await },
|
||||||
|
None => {
|
||||||
pub fn exec_tx(&self) -> mpsc::Sender<ExecutorCommand> {
|
log(msg!(ERROR, "No Connector Availiable"));
|
||||||
return self.exec_tx.clone();
|
todo!("Implement node level connection cmd fail");
|
||||||
}
|
|
||||||
|
|
||||||
async fn connector_cmd(&self, cmd: ConnectorCommand) {
|
|
||||||
match &self.tcp_connector {
|
|
||||||
Some(t) => match t.send(cmd).await {
|
|
||||||
Ok(()) => {}
|
|
||||||
Err(e) => log(msg!(ERROR, "Failed to Send Command to connector: {}", e)),
|
|
||||||
},
|
},
|
||||||
None => log(msg!(ERROR, "No Connector Availiable")),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn start_connection_listner(&mut self, addr: SocketAddr) {
|
async fn start_connection_listner(&mut self, addr: SocketAddr) {
|
||||||
log(msg!(DEBUG, "Starting Connection Listener"));
|
log(msg!(DEBUG, "Starting Connection Listener"));
|
||||||
let (con_tx, con_rx) = mpsc::channel::<ConnectorCommand>(100);
|
|
||||||
|
|
||||||
self.tcp_connector = Some(con_tx);
|
let connector = Connector::new(self.id.clone(), addr);
|
||||||
|
|
||||||
self.listner_handle = Some(tokio::spawn({
|
|
||||||
let mut connector = Connector::new(self.id.clone(), addr, self.exec_tx(), con_rx);
|
|
||||||
log(msg!(DEBUG, "Connector Build"));
|
log(msg!(DEBUG, "Connector Build"));
|
||||||
async move { connector.start().await }
|
self.tcp_connector = Some(connector);
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn connect_to_seed(&mut self) {
|
async fn connect_to_seed(&mut self) {
|
||||||
@ -337,8 +303,7 @@ impl Node {
|
|||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn accept_command(&mut self) {
|
pub async fn command(&mut self, command: NodeCommand) {
|
||||||
while let Some(command) = self.rx.recv().await {
|
|
||||||
match command {
|
match command {
|
||||||
NodeCommand::BootStrap => {
|
NodeCommand::BootStrap => {
|
||||||
log(msg!(DEBUG, "Received NodeCommand::BootStrap"));
|
log(msg!(DEBUG, "Received NodeCommand::BootStrap"));
|
||||||
@ -417,7 +382,7 @@ impl Node {
|
|||||||
let wat_cmd = WatcherCommand::SetMode(WatcherMode::Select {
|
let wat_cmd = WatcherCommand::SetMode(WatcherMode::Select {
|
||||||
content: blocks.iter().map(|h| hex::encode(h)).collect::<Vec<String>>().into(),
|
content: blocks.iter().map(|h| hex::encode(h)).collect::<Vec<String>>().into(),
|
||||||
title: "Select Block to display".to_string(),
|
title: "Select Block to display".to_string(),
|
||||||
callback: Box::new(ExecutorCommand::Node(NodeCommand::DisplayBlockByKey("".to_string()))),
|
callback: Box::new(WatcherCommand::Node(NodeCommand::DisplayBlockByKey("".to_string()))),
|
||||||
index: 0
|
index: 0
|
||||||
});
|
});
|
||||||
publish_watcher_event(wat_cmd);
|
publish_watcher_event(wat_cmd);
|
||||||
@ -445,13 +410,11 @@ impl Node {
|
|||||||
}
|
}
|
||||||
NodeCommand::Exit => {
|
NodeCommand::Exit => {
|
||||||
log(msg!(DEBUG, "Node Exit"));
|
log(msg!(DEBUG, "Node Exit"));
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn run(&mut self) {
|
pub async fn init(&mut self) {
|
||||||
if let Some(addr) = self.addr {
|
if let Some(addr) = self.addr {
|
||||||
self.start_connection_listner(addr).await;
|
self.start_connection_listner(addr).await;
|
||||||
} else {
|
} else {
|
||||||
@ -463,46 +426,31 @@ impl Node {
|
|||||||
.await;
|
.await;
|
||||||
};
|
};
|
||||||
|
|
||||||
let http_handle = tokio::spawn(async move {
|
let _http_handle = tokio::spawn(async move {
|
||||||
let _ = crate::api::server::start_server().await;
|
let _ = crate::api::server::start_server().await;
|
||||||
});
|
});
|
||||||
|
|
||||||
let (_tx, rx) = mpsc::channel::<WsCommand>(100);
|
// let (_tx, rx) = mpsc::channel::<WsCommand>(100);
|
||||||
|
|
||||||
let mut ws_server = WsServer::new(rx, self.exec_tx());
|
// let mut ws_server = WsServer::new(rx, self.exec_tx());
|
||||||
|
|
||||||
let _ws_handle = tokio::spawn(async move {
|
// let _ws_handle = tokio::spawn(async move {
|
||||||
if let Err(e) = ws_server.run().await {
|
// if let Err(e) = ws_server.run().await {
|
||||||
print_error_chain(&e.into());
|
// print_error_chain(&e.into());
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
|
|
||||||
let mut system_rx = subscribe_system_event();
|
let mut _system_rx = subscribe_system_event();
|
||||||
publish_system_event(SystemEvent::NodeStarted);
|
publish_system_event(SystemEvent::NodeStarted);
|
||||||
|
|
||||||
self.chain.recover_mempool();
|
self.chain.recover_mempool();
|
||||||
|
}
|
||||||
|
|
||||||
loop {
|
pub async fn poll(&mut self) -> Option<()> {
|
||||||
select! {
|
tokio::select! {
|
||||||
_ = self.accept_command() => {
|
_con_cmd = self.tcp_connector.as_mut()?.poll() => {
|
||||||
|
None
|
||||||
}
|
|
||||||
event_result = system_rx.recv() => {
|
|
||||||
match event_result {
|
|
||||||
Ok(e) => {
|
|
||||||
match e {
|
|
||||||
SystemEvent::Shutdown => {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
http_handle.abort_handle().abort();
|
|
||||||
self.shutdown().await;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,7 @@
|
|||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
|
|
||||||
use tokio::sync::mpsc;
|
|
||||||
use vlogger::*;
|
use vlogger::*;
|
||||||
|
|
||||||
use crate::bus::{NetworkEvent, SystemEvent, subscribe_system_event};
|
|
||||||
use crate::executor::{Executor, ExecutorCommand};
|
|
||||||
use crate::{log, node};
|
use crate::{log, node};
|
||||||
use crate::node::{Node, NodeCommand};
|
use crate::node::{Node, NodeCommand};
|
||||||
use cli_renderer::{RenderLayoutKind, Renderer};
|
use cli_renderer::{RenderLayoutKind, Renderer};
|
||||||
@ -62,8 +59,6 @@ impl WatcherBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn start(mut self) -> Watcher {
|
pub async fn start(mut self) -> Watcher {
|
||||||
let (exec_tx, exec_rx) = mpsc::channel::<ExecutorCommand>(100);
|
|
||||||
let mut sys_event = subscribe_system_event();
|
|
||||||
|
|
||||||
if self.debug {
|
if self.debug {
|
||||||
Watcher::log_memory().await;
|
Watcher::log_memory().await;
|
||||||
@ -77,79 +72,25 @@ impl WatcherBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let chain = node::Blockchain::new(self.database, self.temporary).unwrap();
|
let chain = node::Blockchain::new(self.database, self.temporary).unwrap();
|
||||||
let mut node = Node::new(self.addr.clone(), exec_tx.clone(), chain);
|
let mut node = Node::new(self.addr.clone(), chain);
|
||||||
|
node.init().await;
|
||||||
|
|
||||||
log(msg!(INFO, "Built Node"));
|
log(msg!(INFO, "Built Node"));
|
||||||
|
|
||||||
let executor_handle = tokio::spawn({
|
|
||||||
let node_tx = node.tx();
|
|
||||||
async move {
|
|
||||||
let _ = Executor::new(node_tx, exec_rx).run().await;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
for i in 0..3 {
|
|
||||||
if let Ok(ev) = sys_event.recv().await {
|
|
||||||
match ev {
|
|
||||||
SystemEvent::ExecutorStarted => {
|
|
||||||
log(msg!(INFO, "Executor Started"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
_ => log(msg!(WARNING, "Wrong Event: {ev:?}! Retrying... (try {i})")),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let node_tx = node.tx();
|
|
||||||
let node_handle = tokio::spawn({
|
|
||||||
async move {
|
|
||||||
node.run().await;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
for i in 0..3 {
|
|
||||||
if let Ok(ev) = sys_event.recv().await {
|
|
||||||
match ev {
|
|
||||||
SystemEvent::NodeStarted => {
|
|
||||||
log(msg!(INFO, "Executor Started"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
_ => log(msg!(WARNING, "Wrong Event: {ev:?}! Retrying... (try {i})")),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.bootstrap {
|
if self.bootstrap {
|
||||||
let exec_tx = exec_tx.clone();
|
node.command(NodeCommand::BootStrap).await;
|
||||||
|
|
||||||
tokio::spawn(async move {
|
|
||||||
let seed_cmd = ExecutorCommand::Node(NodeCommand::ConnectToSeeds);
|
|
||||||
let mut ev_rx = crate::bus::subscribe_network_event();
|
|
||||||
let _ = exec_tx.send(seed_cmd).await;
|
|
||||||
|
|
||||||
while let Ok(e) = ev_rx.recv().await {
|
|
||||||
match e {
|
|
||||||
NetworkEvent::SeedConnected(_) => {
|
|
||||||
let bootstrap_cmd = ExecutorCommand::Node(NodeCommand::BootStrap);
|
|
||||||
let _ = exec_tx.send(bootstrap_cmd).await;
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let cmd_history = Vec::new();
|
let cmd_history = Vec::new();
|
||||||
let history_index = 0;
|
let history_index = 0;
|
||||||
let cmd_buffer = String::new();
|
let cmd_buffer = String::new();
|
||||||
let handles = vec![executor_handle, node_handle];
|
|
||||||
Watcher::new(
|
Watcher::new(
|
||||||
node_tx,
|
|
||||||
exec_tx,
|
|
||||||
cmd_buffer,
|
cmd_buffer,
|
||||||
cmd_history,
|
cmd_history,
|
||||||
history_index,
|
history_index,
|
||||||
handles,
|
|
||||||
renderer,
|
renderer,
|
||||||
|
node,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,19 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use cli_renderer::RenderCommand;
|
use cli_renderer::RenderCommand;
|
||||||
use crate::executor::ExecutorCommand;
|
|
||||||
|
use crate::node::NodeCommand;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum WatcherCommand {
|
pub enum WatcherCommand {
|
||||||
|
NodeResponse(String),
|
||||||
|
Node(NodeCommand),
|
||||||
|
Echo(Vec<String>),
|
||||||
|
Print(String),
|
||||||
|
InvalidCommand(String),
|
||||||
Render(RenderCommand),
|
Render(RenderCommand),
|
||||||
SetMode(WatcherMode),
|
SetMode(WatcherMode),
|
||||||
|
Exit,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@ -15,7 +22,7 @@ pub enum WatcherMode {
|
|||||||
Select{
|
Select{
|
||||||
content: Arc<Vec<String>>,
|
content: Arc<Vec<String>>,
|
||||||
title: String,
|
title: String,
|
||||||
callback: Box<ExecutorCommand>,
|
callback: Box<WatcherCommand>,
|
||||||
index: usize,
|
index: usize,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
bus::{publish_system_event, subscribe_system_event, SystemEvent},
|
bus::{SystemEvent, publish_system_event, subscribe_system_event}, cli::cli, node::{Node, node::NodeCommand}, watcher::WatcherMode
|
||||||
cli::cli,
|
|
||||||
node::node::NodeCommand,
|
|
||||||
watcher::WatcherMode
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use shared::print_error_chain;
|
use shared::print_error_chain;
|
||||||
@ -12,7 +9,6 @@ use memory_stats::memory_stats;
|
|||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
use tokio::{
|
use tokio::{
|
||||||
select,
|
select,
|
||||||
sync::mpsc,
|
|
||||||
time::{Duration, interval},
|
time::{Duration, interval},
|
||||||
};
|
};
|
||||||
use vlogger::*;
|
use vlogger::*;
|
||||||
@ -20,7 +16,6 @@ use vlogger::*;
|
|||||||
use super::{ WatcherBuilder, WatcherCommand };
|
use super::{ WatcherBuilder, WatcherCommand };
|
||||||
|
|
||||||
use crate::bus::subscribe_watcher_event;
|
use crate::bus::subscribe_watcher_event;
|
||||||
use crate::executor::*;
|
|
||||||
use crate::log;
|
use crate::log;
|
||||||
|
|
||||||
use cli_renderer::{
|
use cli_renderer::{
|
||||||
@ -31,35 +26,29 @@ use cli_renderer::{
|
|||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub struct Watcher {
|
pub struct Watcher {
|
||||||
node_tx: mpsc::Sender<NodeCommand>,
|
|
||||||
exec_tx: mpsc::Sender<ExecutorCommand>,
|
|
||||||
cmd_buffer: String,
|
cmd_buffer: String,
|
||||||
cmd_history: Vec<String>,
|
cmd_history: Vec<String>,
|
||||||
history_index: usize,
|
history_index: usize,
|
||||||
handles: Vec<tokio::task::JoinHandle<()>>,
|
|
||||||
event_stream: crossterm::event::EventStream,
|
event_stream: crossterm::event::EventStream,
|
||||||
mode: WatcherMode,
|
mode: WatcherMode,
|
||||||
pub renderer: Renderer,
|
pub renderer: Renderer,
|
||||||
|
node: Node,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Watcher {
|
impl Watcher {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
node_tx: mpsc::Sender<NodeCommand>,
|
|
||||||
exec_tx: mpsc::Sender<ExecutorCommand>,
|
|
||||||
cmd_buffer: String,
|
cmd_buffer: String,
|
||||||
cmd_history: Vec<String>,
|
cmd_history: Vec<String>,
|
||||||
history_index: usize,
|
history_index: usize,
|
||||||
handles: Vec<tokio::task::JoinHandle<()>>,
|
|
||||||
renderer: Renderer,
|
renderer: Renderer,
|
||||||
|
node: Node,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
node_tx,
|
|
||||||
exec_tx,
|
|
||||||
cmd_buffer,
|
cmd_buffer,
|
||||||
cmd_history,
|
cmd_history,
|
||||||
history_index,
|
history_index,
|
||||||
handles,
|
|
||||||
renderer,
|
renderer,
|
||||||
|
node,
|
||||||
mode: WatcherMode::Input,
|
mode: WatcherMode::Input,
|
||||||
event_stream: EventStream::new(),
|
event_stream: EventStream::new(),
|
||||||
}
|
}
|
||||||
@ -76,10 +65,6 @@ impl Watcher {
|
|||||||
|
|
||||||
async fn shutdown(&mut self) -> io::Result<()> {
|
async fn shutdown(&mut self) -> io::Result<()> {
|
||||||
ratatui::restore();
|
ratatui::restore();
|
||||||
let handles = std::mem::take(&mut self.handles);
|
|
||||||
for handle in handles {
|
|
||||||
handle.await.unwrap()
|
|
||||||
}
|
|
||||||
crossterm::execute!(
|
crossterm::execute!(
|
||||||
std::io::stdout(),
|
std::io::stdout(),
|
||||||
crossterm::event::DisableBracketedPaste,
|
crossterm::event::DisableBracketedPaste,
|
||||||
@ -88,24 +73,6 @@ impl Watcher {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_cmd(&mut self, cmd: WatcherCommand) {
|
|
||||||
match cmd {
|
|
||||||
WatcherCommand::Render(rend_cmd) => {
|
|
||||||
self.renderer.apply(rend_cmd);
|
|
||||||
}
|
|
||||||
WatcherCommand::SetMode(mode) => {
|
|
||||||
match &mode {
|
|
||||||
WatcherMode::Input => {}
|
|
||||||
WatcherMode::Select{content, title, ..} => {
|
|
||||||
let rd_cmd = RenderCommand::SetMode(InputMode::PopUp(content.clone(), title.clone(), 0));
|
|
||||||
self.renderer.apply(rd_cmd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.mode = mode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn run(&mut self) -> std::io::Result<()> {
|
pub async fn run(&mut self) -> std::io::Result<()> {
|
||||||
let mut ui_rx = subscribe_watcher_event();
|
let mut ui_rx = subscribe_watcher_event();
|
||||||
let mut render_interval = interval(Duration::from_millis(32));
|
let mut render_interval = interval(Duration::from_millis(32));
|
||||||
@ -132,7 +99,7 @@ impl Watcher {
|
|||||||
match ui_event {
|
match ui_event {
|
||||||
Ok(cmd) => {
|
Ok(cmd) => {
|
||||||
self.renderer.set_area(terminal.get_frame().area());
|
self.renderer.set_area(terminal.get_frame().area());
|
||||||
self.handle_cmd(cmd);
|
self.command(cmd);
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log(msg!(ERROR, "{}", e))
|
log(msg!(ERROR, "{}", e))
|
||||||
@ -162,31 +129,68 @@ impl Watcher {
|
|||||||
WatcherBuilder::new()
|
WatcherBuilder::new()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exec_tx(&self) -> mpsc::Sender<ExecutorCommand> {
|
fn exit(&mut self) {
|
||||||
self.exec_tx.clone()
|
log(msg!(DEBUG, "Watcher Exit"));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exit(&self) {}
|
fn echo(&mut self, s: Vec<String>) {
|
||||||
|
let mut str = s.join(" ");
|
||||||
|
str.push_str("\n");
|
||||||
|
self.renderer.apply(RenderCommand::StringToPaneId {
|
||||||
|
str,
|
||||||
|
pane: cli_renderer::RenderTarget::CliOutput,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn invalid_command(&mut self, str: String) {
|
||||||
|
self.renderer.apply(RenderCommand::StringToPaneId {
|
||||||
|
str,
|
||||||
|
pane: cli_renderer::RenderTarget::CliOutput,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_mode(&mut self, mode: WatcherMode) {
|
||||||
|
match &mode {
|
||||||
|
WatcherMode::Input => {}
|
||||||
|
WatcherMode::Select{content, title, ..} => {
|
||||||
|
let rd_cmd = RenderCommand::SetMode(InputMode::PopUp(content.clone(), title.clone(), 0));
|
||||||
|
self.renderer.apply(rd_cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.mode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn command(&mut self, cmd: WatcherCommand) {
|
||||||
|
match cmd {
|
||||||
|
WatcherCommand::NodeResponse(resp) => log(resp),
|
||||||
|
WatcherCommand::Node(n) => self.node.command(n).await,
|
||||||
|
WatcherCommand::Render(p) => self.renderer.apply(p),
|
||||||
|
WatcherCommand::Echo(s) => self.echo(s),
|
||||||
|
WatcherCommand::Print(s) => log(s),
|
||||||
|
WatcherCommand::InvalidCommand(str) => self.invalid_command(str).await,
|
||||||
|
WatcherCommand::Exit => self.exit(),
|
||||||
|
WatcherCommand::SetMode(mode) => self.set_mode(mode),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn handle_enter(&mut self) {
|
async fn handle_enter(&mut self) {
|
||||||
match &self.mode {
|
match &self.mode {
|
||||||
WatcherMode::Input => {
|
WatcherMode::Input => {
|
||||||
if !self.cmd_buffer.is_empty() {
|
if !self.cmd_buffer.is_empty() {
|
||||||
let exec_event = cli(&self.cmd_buffer);
|
let exec_event = cli(&self.cmd_buffer);
|
||||||
let _ = self.exec_tx.send(exec_event).await;
|
self.command(exec_event).await;
|
||||||
self.cmd_buffer.clear();
|
self.cmd_buffer.clear();
|
||||||
self.renderer.handle_enter()
|
self.renderer.handle_enter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
WatcherMode::Select { content, callback, index, .. } => {
|
WatcherMode::Select { content, callback, index, .. } => {
|
||||||
match &&**callback {
|
match &&**callback {
|
||||||
&ExecutorCommand::Node(nd_cmd) => {
|
&WatcherCommand::Node(nd_cmd) => {
|
||||||
match nd_cmd {
|
match nd_cmd {
|
||||||
NodeCommand::DisplayBlockByKey(_) => {
|
NodeCommand::DisplayBlockByKey(_) => {
|
||||||
let key = (*content)[*index].clone().to_string();
|
let key = (*content)[*index].clone().to_string();
|
||||||
log(msg!(DEBUG, "KEY IN ENTER: {key}"));
|
log(msg!(DEBUG, "KEY IN ENTER: {key}"));
|
||||||
let resp = ExecutorCommand::Node(NodeCommand::DisplayBlockByKey(key));
|
self.node.command(NodeCommand::DisplayBlockByKey(key));
|
||||||
let _ = self.exec_tx.send(resp).await;
|
|
||||||
}
|
}
|
||||||
_ => {log(msg!(DEBUG, "TODO: Implement callback for {:?}", nd_cmd))}
|
_ => {log(msg!(DEBUG, "TODO: Implement callback for {:?}", nd_cmd))}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user