bless
This commit is contained in:
parent
a882d6684e
commit
4b6801644b
@ -1,3 +1,5 @@
|
|||||||
|
use std::net::SocketAddr;
|
||||||
|
|
||||||
use clap::{Parser, Subcommand};
|
use clap::{Parser, Subcommand};
|
||||||
use crate::core;
|
use crate::core;
|
||||||
|
|
||||||
@ -6,7 +8,7 @@ use crate::core;
|
|||||||
pub struct Args {
|
pub struct Args {
|
||||||
/// Provide address on which node will listen
|
/// Provide address on which node will listen
|
||||||
#[arg(short = 'a', long)]
|
#[arg(short = 'a', long)]
|
||||||
pub addr: Option<String>,
|
pub addr: Option<SocketAddr>,
|
||||||
|
|
||||||
/// Provide File with current chain
|
/// Provide File with current chain
|
||||||
#[arg(short = 'f', long)]
|
#[arg(short = 'f', long)]
|
||||||
|
|||||||
17
src/main.rs
17
src/main.rs
@ -1,5 +1,3 @@
|
|||||||
use error::{ BlockchainError, handle_error };
|
|
||||||
|
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod args;
|
pub mod args;
|
||||||
pub mod core;
|
pub mod core;
|
||||||
@ -9,28 +7,19 @@ pub mod watcher;
|
|||||||
|
|
||||||
use crate::{args::get_args, watcher::watcher::Watcher};
|
use crate::{args::get_args, watcher::watcher::Watcher};
|
||||||
|
|
||||||
const SEED_ADDR: &str = "127.0.0.1:8333";
|
|
||||||
|
|
||||||
fn add_transaction(tx: core::Tx) -> Result<(), BlockchainError> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn list_accounts() {
|
|
||||||
println!("Account Balances:\n-----------------");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
|
|
||||||
let args = get_args();
|
let args = get_args();
|
||||||
|
|
||||||
let mut watcher = Watcher::build().file(args.seed_file).addr(args.addr).start();
|
let mut watcher = Watcher::build().file(args.seed_file).addr(args.addr).start().await;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
if !watcher.poll().await.is_ok() {
|
if watcher.poll().await.is_ok_and(|b| b) {
|
||||||
break ;
|
break ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ratatui::restore();
|
||||||
println!("Hello, world!");
|
println!("Hello, world!");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
use std::net::SocketAddr;
|
||||||
|
|
||||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||||
use tokio::net;
|
use tokio::net;
|
||||||
use crate::native_node::node;
|
use crate::native_node::node;
|
||||||
@ -19,7 +21,7 @@ pub enum ProtocolMessage {
|
|||||||
peer_id: uuid::Uuid
|
peer_id: uuid::Uuid
|
||||||
},
|
},
|
||||||
GetPeersResponse {
|
GetPeersResponse {
|
||||||
peer_addresses: Vec<String>
|
peer_addresses: Vec<SocketAddr>
|
||||||
},
|
},
|
||||||
Handshake { node_id: uuid::Uuid, version: String },
|
Handshake { node_id: uuid::Uuid, version: String },
|
||||||
Block { peer_id: uuid::Uuid, height: u64, block: core::Block },
|
Block { peer_id: uuid::Uuid, height: u64, block: core::Block },
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
use std::net::SocketAddr;
|
||||||
|
|
||||||
use crate::native_node::{message, node};
|
use crate::native_node::{message, node};
|
||||||
|
|
||||||
use crate::seeds_constants::SEED_NODES;
|
use crate::seeds_constants::SEED_NODES;
|
||||||
@ -8,12 +10,14 @@ use tokio::sync::mpsc;
|
|||||||
|
|
||||||
impl node::NativeNode {
|
impl node::NativeNode {
|
||||||
pub async fn connect_to_seeds(&mut self, sender: mpsc::Sender<node::NodeCommand>) {
|
pub async fn connect_to_seeds(&mut self, sender: mpsc::Sender<node::NodeCommand>) {
|
||||||
for seed in SEED_NODES {
|
for seed in SEED_NODES.iter() {
|
||||||
if seed != self.addr {
|
if let Some(a)= self.addr {
|
||||||
|
if *seed != a {
|
||||||
if let Ok(mut stream) = tokio::net::TcpStream::connect(seed).await {
|
if let Ok(mut stream) = tokio::net::TcpStream::connect(seed).await {
|
||||||
if let Ok(peer_id) = node::NativeNode::send_handshake(self.id.clone(), &mut stream).await {
|
if let Ok(peer_id) = node::NativeNode::send_handshake(self.id.clone(), &mut stream).await {
|
||||||
let sender = sender.clone();
|
let sender = sender.clone();
|
||||||
node::NativeNode::establish_connection(peer_id, seed.to_string(), stream, sender).await;
|
node::NativeNode::establish_connection(peer_id, *seed, stream, sender).await;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -22,7 +26,7 @@ impl node::NativeNode {
|
|||||||
|
|
||||||
pub async fn establish_connection(
|
pub async fn establish_connection(
|
||||||
peer_id: uuid::Uuid,
|
peer_id: uuid::Uuid,
|
||||||
addr: String,
|
addr: SocketAddr,
|
||||||
stream: tokio::net::TcpStream,
|
stream: tokio::net::TcpStream,
|
||||||
request_sender: tokio::sync::mpsc::Sender<node::NodeCommand>
|
request_sender: tokio::sync::mpsc::Sender<node::NodeCommand>
|
||||||
) {
|
) {
|
||||||
@ -59,7 +63,7 @@ impl node::NativeNode {
|
|||||||
if let Ok(message) = node::NativeNode::receive_message(&mut stream).await {
|
if let Ok(message) = node::NativeNode::receive_message(&mut stream).await {
|
||||||
match message {
|
match message {
|
||||||
message::ProtocolMessage::Handshake { node_id, .. } => {
|
message::ProtocolMessage::Handshake { node_id, .. } => {
|
||||||
node::NativeNode::establish_connection(node_id, addr.to_string(), stream, request_sender.clone()).await;
|
node::NativeNode::establish_connection(node_id, addr, stream, request_sender.clone()).await;
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
log!(WARNING, "Invalid Response! expected Handshake, got {:?}", message);
|
log!(WARNING, "Invalid Response! expected Handshake, got {:?}", message);
|
||||||
|
|||||||
@ -5,45 +5,52 @@ use crate::seeds_constants::SEED_NODES;
|
|||||||
use crate::watcher::executor::ExecutorCommand;
|
use crate::watcher::executor::ExecutorCommand;
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::net::SocketAddr;
|
||||||
use vlogger::*;
|
use vlogger::*;
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
pub struct TcpPeer {
|
pub struct TcpPeer {
|
||||||
pub id: Uuid,
|
pub id: Uuid,
|
||||||
pub addr: String,
|
pub addr: SocketAddr,
|
||||||
pub sender: tokio::sync::mpsc::Sender<ProtocolMessage>
|
pub sender: tokio::sync::mpsc::Sender<ProtocolMessage>
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct NativeNode {
|
pub struct NativeNode {
|
||||||
pub id: Uuid,
|
pub id: Uuid,
|
||||||
pub addr: String,
|
pub addr: Option<SocketAddr>,
|
||||||
pub tcp_peers: HashMap<Uuid, TcpPeer>,
|
pub tcp_peers: HashMap<Uuid, TcpPeer>,
|
||||||
pub chain: core::Blockchain,
|
pub chain: core::Blockchain,
|
||||||
|
listner_handle: Option<tokio::task::JoinHandle<()>>,
|
||||||
exec_tx: mpsc::Sender<ExecutorCommand>,
|
exec_tx: mpsc::Sender<ExecutorCommand>,
|
||||||
rx: mpsc::Receiver<NodeCommand>,
|
rx: mpsc::Receiver<NodeCommand>,
|
||||||
|
tx: mpsc::Sender<NodeCommand>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum NodeCommand {
|
pub enum NodeCommand {
|
||||||
AddPeer { peer_id: Uuid, addr: String, sender: tokio::sync::mpsc::Sender<ProtocolMessage> },
|
AddPeer { peer_id: Uuid, addr: SocketAddr, sender: tokio::sync::mpsc::Sender<ProtocolMessage> },
|
||||||
RemovePeer { peer_id: Uuid },
|
RemovePeer { peer_id: Uuid },
|
||||||
ProcessMessage { peer_id: Uuid, message: ProtocolMessage },
|
ProcessMessage { peer_id: Uuid, message: ProtocolMessage },
|
||||||
Transaction { tx: core::Tx },
|
Transaction { tx: core::Tx },
|
||||||
|
StartListner(SocketAddr),
|
||||||
CreateBlock,
|
CreateBlock,
|
||||||
DebugListBlocks,
|
DebugListBlocks,
|
||||||
DebugListPeers,
|
DebugListPeers,
|
||||||
DebugShowId,
|
DebugShowId,
|
||||||
DebugDumpBlocks,
|
DebugDumpBlocks,
|
||||||
ConnectToSeeds
|
ConnectToSeeds,
|
||||||
|
Exit,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl NativeNode {
|
impl NativeNode {
|
||||||
|
|
||||||
pub fn peer_addresses(&self) -> Vec<String> {
|
pub fn peer_addresses(&self) -> Vec<SocketAddr> {
|
||||||
let mut addr: Vec<String> = self.tcp_peers.iter().map(|p| p.1.addr.to_string()).collect();
|
let mut addr: Vec<SocketAddr> = self.tcp_peers.iter().map(|p| p.1.addr.to_string().parse::<SocketAddr>().unwrap()).collect();
|
||||||
addr.push(self.addr.clone());
|
if let Some(a) = self.addr {
|
||||||
|
addr.push(a.clone());
|
||||||
|
}
|
||||||
addr
|
addr
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,7 +70,7 @@ impl NativeNode {
|
|||||||
self.tcp_peers.remove_entry(&peer_id);
|
self.tcp_peers.remove_entry(&peer_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_tcp_peer(&mut self, id: Uuid, addr: String, sender: tokio::sync::mpsc::Sender<ProtocolMessage>) {
|
fn add_tcp_peer(&mut self, id: Uuid, addr: SocketAddr, sender: tokio::sync::mpsc::Sender<ProtocolMessage>) {
|
||||||
let peer = TcpPeer {
|
let peer = TcpPeer {
|
||||||
id: id,
|
id: id,
|
||||||
addr,
|
addr,
|
||||||
@ -78,24 +85,34 @@ impl NativeNode {
|
|||||||
pub fn new_with_id(
|
pub fn new_with_id(
|
||||||
id: uuid::Uuid,
|
id: uuid::Uuid,
|
||||||
exec_tx: mpsc::Sender<ExecutorCommand>,
|
exec_tx: mpsc::Sender<ExecutorCommand>,
|
||||||
rx: mpsc::Receiver<NodeCommand>
|
addr: Option<SocketAddr>,
|
||||||
|
blocks: Option<Vec<core::Block>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
let (tx, rx) = mpsc::channel::<NodeCommand>(100);
|
||||||
Self {
|
Self {
|
||||||
id,
|
id,
|
||||||
tcp_peers: HashMap::new(),
|
tcp_peers: HashMap::new(),
|
||||||
chain: Default::default(),
|
chain: {
|
||||||
addr: String::new(),
|
if blocks.is_some() {
|
||||||
|
Blockchain::build(blocks.unwrap()).unwrap_or(Default::default())
|
||||||
|
} else {
|
||||||
|
Default::default()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
addr,
|
||||||
exec_tx,
|
exec_tx,
|
||||||
|
listner_handle: None,
|
||||||
|
tx,
|
||||||
rx,
|
rx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(
|
pub fn new(
|
||||||
addr: Option<String>,
|
addr: Option<SocketAddr>,
|
||||||
blocks: Option<Vec<core::Block>>,
|
blocks: Option<Vec<core::Block>>,
|
||||||
exec_tx: mpsc::Sender<ExecutorCommand>,
|
exec_tx: mpsc::Sender<ExecutorCommand>,
|
||||||
rx: mpsc::Receiver<NodeCommand>,
|
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
let (tx, rx) = mpsc::channel::<NodeCommand>(100);
|
||||||
Self {
|
Self {
|
||||||
id: Uuid::new_v4(),
|
id: Uuid::new_v4(),
|
||||||
tcp_peers: HashMap::new(),
|
tcp_peers: HashMap::new(),
|
||||||
@ -106,9 +123,11 @@ impl NativeNode {
|
|||||||
Default::default()
|
Default::default()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
addr: if addr.is_some() { addr.unwrap() } else { String::new() },
|
addr,
|
||||||
exec_tx,
|
exec_tx,
|
||||||
rx
|
listner_handle: None,
|
||||||
|
tx,
|
||||||
|
rx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,22 +200,39 @@ impl NativeNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn run_native(&mut self) {
|
pub fn tx(&self) -> mpsc::Sender<NodeCommand> {
|
||||||
let tcp_listner = tokio::net::TcpListener::bind(&self.addr).await.unwrap();
|
return self.tx.clone()
|
||||||
|
}
|
||||||
|
|
||||||
let (channel_write, mut channel_read) = mpsc::channel::<NodeCommand>(100);
|
async fn start_connection_listner(&mut self, addr: SocketAddr) {
|
||||||
|
if self.listner_handle.is_some() {
|
||||||
|
self.listner_handle.as_ref().unwrap().abort();
|
||||||
|
self.listner_handle = None;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Ok(tcp_listner) = tokio::net::TcpListener::bind(addr).await {
|
||||||
let id = self.id.clone();
|
let id = self.id.clone();
|
||||||
tokio::spawn({
|
let node_tx = self.tx();
|
||||||
let c = channel_write.clone();
|
self.listner_handle = Some(tokio::spawn({
|
||||||
async move {
|
async move {
|
||||||
NativeNode::accept_connections(tcp_listner, c, id).await;
|
NativeNode::accept_connections(tcp_listner, node_tx, id).await;
|
||||||
}});
|
}}))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
while let Some(command) = channel_read.recv().await {
|
pub async fn run_native(&mut self) {
|
||||||
|
|
||||||
|
if let Some(a) = self.addr {
|
||||||
|
self.start_connection_listner(a.clone()).await;
|
||||||
|
};
|
||||||
|
|
||||||
|
while let Some(command) = self.rx.recv().await {
|
||||||
match command {
|
match command {
|
||||||
|
NodeCommand::StartListner(addr) => {
|
||||||
|
self.start_connection_listner(addr).await;
|
||||||
|
}
|
||||||
NodeCommand::ConnectToSeeds => {
|
NodeCommand::ConnectToSeeds => {
|
||||||
self.connect_to_seeds(channel_write.clone()).await;
|
self.connect_to_seeds(self.tx()).await;
|
||||||
},
|
},
|
||||||
NodeCommand::AddPeer { peer_id, addr, sender } => {
|
NodeCommand::AddPeer { peer_id, addr, sender } => {
|
||||||
self.add_tcp_peer(peer_id, addr, sender);
|
self.add_tcp_peer(peer_id, addr, sender);
|
||||||
@ -231,6 +267,10 @@ impl NativeNode {
|
|||||||
NodeCommand::DebugDumpBlocks => {
|
NodeCommand::DebugDumpBlocks => {
|
||||||
// self.chain.dump_blocks(&mut self.db_file);
|
// self.chain.dump_blocks(&mut self.db_file);
|
||||||
}
|
}
|
||||||
|
NodeCommand::Exit => {
|
||||||
|
log!(DEBUG, "Node Exit");
|
||||||
|
break ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,8 @@
|
|||||||
pub const SEED_NODES: [&str; 1] = [
|
use once_cell::sync::Lazy;
|
||||||
"127.0.0.1:8333"
|
use std::net::{SocketAddr, IpAddr, Ipv4Addr};
|
||||||
];
|
|
||||||
|
pub static SEED_NODES: Lazy<[SocketAddr; 3]> = Lazy::new(|| [
|
||||||
|
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8333),
|
||||||
|
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(192, 168, 1, 1)), 3000),
|
||||||
|
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)), 5432),
|
||||||
|
]);
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
use crate::{native_node::node::NodeCommand, watcher::renderer::*};
|
use crate::{native_node::node::NodeCommand, watcher::renderer::*};
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
|
use vlogger::*;
|
||||||
|
|
||||||
pub enum ExecutorCommand {
|
pub enum ExecutorCommand {
|
||||||
NodeResponse(String),
|
NodeResponse(String),
|
||||||
@ -28,6 +29,7 @@ impl Executor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn exit(&mut self) {
|
fn exit(&mut self) {
|
||||||
|
log!(DEBUG, "Executor Exit");
|
||||||
self.exit = true
|
self.exit = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
use std::net::SocketAddr;
|
||||||
|
|
||||||
use crate::native_node::node::NodeCommand;
|
use crate::native_node::node::NodeCommand;
|
||||||
use crate::watcher::executor::{ExecutorCommand};
|
use crate::watcher::executor::{ExecutorCommand};
|
||||||
use vlogger::*;
|
use vlogger::*;
|
||||||
@ -50,6 +52,7 @@ impl Parser {
|
|||||||
|
|
||||||
async fn listen(&mut self) {
|
async fn listen(&mut self) {
|
||||||
if let Ok(Some(mes)) = timeout(Duration::from_millis(400), self.rx.recv()).await {
|
if let Ok(Some(mes)) = timeout(Duration::from_millis(400), self.rx.recv()).await {
|
||||||
|
log!(DEBUG, "Parser: Received message from watcher");
|
||||||
match mes {
|
match mes {
|
||||||
ParserCommand::ParseCmdString(s) => {
|
ParserCommand::ParseCmdString(s) => {
|
||||||
let s_split: Vec<&str> = s.split(" ").collect();
|
let s_split: Vec<&str> = s.split(" ").collect();
|
||||||
@ -87,19 +90,31 @@ impl Parser {
|
|||||||
},
|
},
|
||||||
"list" => {
|
"list" => {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
log!(ERROR, "{cmd}: Invalid arg! (blocks, peers)");
|
ExecutorCommand::InvalidCommand(msg!(ERROR, "node list: expects 1 argument"))
|
||||||
}
|
} else {
|
||||||
match args[0] {
|
match args[0] {
|
||||||
"blocks" => ExecutorCommand::Node(NodeCommand::DebugListBlocks),
|
"blocks" => ExecutorCommand::Node(NodeCommand::DebugListBlocks),
|
||||||
"peers" => ExecutorCommand::Node(NodeCommand::DebugListPeers),
|
"peers" => ExecutorCommand::Node(NodeCommand::DebugListPeers),
|
||||||
_ => ExecutorCommand::InvalidCommand(msg!(ERROR, "Unkown arg: {}", args[0])),
|
_ => ExecutorCommand::InvalidCommand(msg!(ERROR, "Unkown arg: {}", args[0])),
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"dump_blocks" => {
|
"dump_blocks" => {
|
||||||
ExecutorCommand::Node(NodeCommand::DebugDumpBlocks)
|
ExecutorCommand::Node(NodeCommand::DebugDumpBlocks)
|
||||||
},
|
},
|
||||||
"connect" => {
|
"connect" => {
|
||||||
ExecutorCommand::Node(NodeCommand::ConnectToSeeds)
|
ExecutorCommand::Node(NodeCommand::ConnectToSeeds)
|
||||||
|
},
|
||||||
|
"listen" => {
|
||||||
|
if args.len() != 1 {
|
||||||
|
ExecutorCommand::InvalidCommand(msg!(ERROR, "node listen: expects 1 argument"))
|
||||||
|
} else {
|
||||||
|
if let Ok(addr) = args[0].parse::<SocketAddr>() {
|
||||||
|
ExecutorCommand::Node(NodeCommand::StartListner(addr))
|
||||||
|
} else {
|
||||||
|
ExecutorCommand::InvalidCommand(msg!(ERROR, "node listen: invalid address {}", args[0]))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
ExecutorCommand::InvalidCommand(msg!(ERROR, "node: unknown argument {}", args[0]))
|
ExecutorCommand::InvalidCommand(msg!(ERROR, "node: unknown argument {}", args[0]))
|
||||||
@ -131,10 +146,11 @@ impl Parser {
|
|||||||
ExecutorCommand::InvalidCommand(msg!(ERROR, "Unknown Command {cmd}"))
|
ExecutorCommand::InvalidCommand(msg!(ERROR, "Unknown Command {cmd}"))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let _ = self.exec_tx.send(exec_cmd);
|
let _ = self.exec_tx.send(exec_cmd).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ParserCommand::Exit => {
|
ParserCommand::Exit => {
|
||||||
|
log!(DEBUG, "Parser Exit");
|
||||||
self.exit();
|
self.exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,9 +7,10 @@ use ratatui::{
|
|||||||
symbols::border,
|
symbols::border,
|
||||||
widgets::{Block, Paragraph, Widget},
|
widgets::{Block, Paragraph, Widget},
|
||||||
DefaultTerminal, Frame,
|
DefaultTerminal, Frame,
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use vlogger::*;
|
||||||
|
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
use tokio::time::{timeout, Duration};
|
use tokio::time::{timeout, Duration};
|
||||||
use std::io;
|
use std::io;
|
||||||
@ -121,6 +122,7 @@ impl Renderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn exit(&mut self) {
|
fn exit(&mut self) {
|
||||||
|
log!(DEBUG, "Renderer Exit");
|
||||||
self.exit = true;
|
self.exit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,9 +2,10 @@ use crate::watcher::*;
|
|||||||
|
|
||||||
use crossterm::{event::{self, Event, KeyCode, KeyEventKind}};
|
use crossterm::{event::{self, Event, KeyCode, KeyEventKind}};
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
use std::io::{self};
|
use std::{io::{self}, net::SocketAddr};
|
||||||
|
|
||||||
use crate::{native_node::node::{NativeNode, NodeCommand}};
|
use crate::{native_node::node::{NativeNode, NodeCommand}};
|
||||||
|
use vlogger::*;
|
||||||
|
|
||||||
pub struct Watcher {
|
pub struct Watcher {
|
||||||
render_tx: mpsc::Sender<RenderCommand>,
|
render_tx: mpsc::Sender<RenderCommand>,
|
||||||
@ -17,7 +18,7 @@ pub struct Watcher {
|
|||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct WatcherBuilder {
|
pub struct WatcherBuilder {
|
||||||
addr: Option<String>,
|
addr: Option<SocketAddr>,
|
||||||
seed_file: Option<String>
|
seed_file: Option<String>
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,6 +27,11 @@ impl Watcher {
|
|||||||
WatcherBuilder::new()
|
WatcherBuilder::new()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn log(&self, msg: String) -> Result<(), mpsc::error::SendError<RenderCommand>> {
|
||||||
|
let rendermsg = RenderCommand::RenderStringToPane { str: msg, pane: RenderPane::CliOutput };
|
||||||
|
self.render_tx.send(rendermsg).await
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn exit(self) {
|
pub async fn exit(self) {
|
||||||
ratatui::restore();
|
ratatui::restore();
|
||||||
// for (i, handle) in self.handles.into_iter().enumerate() {
|
// for (i, handle) in self.handles.into_iter().enumerate() {
|
||||||
@ -41,27 +47,29 @@ impl Watcher {
|
|||||||
KeyCode::Char(c) => {
|
KeyCode::Char(c) => {
|
||||||
self.cmd_buffer.push(c);
|
self.cmd_buffer.push(c);
|
||||||
let message = RenderCommand::RenderInput(k.code);
|
let message = RenderCommand::RenderInput(k.code);
|
||||||
let _ = self.render_tx.send(message);
|
let _ = self.render_tx.send(message).await;
|
||||||
}
|
}
|
||||||
KeyCode::Backspace => {
|
KeyCode::Backspace => {
|
||||||
self.cmd_buffer.pop();
|
self.cmd_buffer.pop();
|
||||||
let message = RenderCommand::RenderInput(k.code);
|
let message = RenderCommand::RenderInput(k.code);
|
||||||
let _ = self.render_tx.send(message);
|
let _ = self.render_tx.send(message).await;
|
||||||
},
|
},
|
||||||
KeyCode::Enter => {
|
KeyCode::Enter => {
|
||||||
let rd_mes = RenderCommand::RenderInput(k.code);
|
let rd_mes = RenderCommand::RenderInput(k.code);
|
||||||
let pr_mes = ParserCommand::ParseCmdString(self.cmd_buffer.clone());
|
let pr_mes = ParserCommand::ParseCmdString(self.cmd_buffer.clone());
|
||||||
let _ = self.render_tx.send(rd_mes);
|
let _ = self.render_tx.send(rd_mes).await;
|
||||||
let _ = self.parser_tx.send(pr_mes);
|
let _ = self.parser_tx.send(pr_mes).await;
|
||||||
self.cmd_buffer.clear();
|
self.cmd_buffer.clear();
|
||||||
}
|
}
|
||||||
KeyCode::Esc => {
|
KeyCode::Esc => {
|
||||||
let rd_mes = RenderCommand::Exit;
|
let rd_mes = RenderCommand::Exit;
|
||||||
let pr_mes = ParserCommand::Exit;
|
let pr_mes = ParserCommand::Exit;
|
||||||
let exec_mes = ExecutorCommand::Exit;
|
let exec_mes = ExecutorCommand::Exit;
|
||||||
let _ = self.render_tx.send(rd_mes);
|
let node_mes = NodeCommand::Exit;
|
||||||
let _ = self.parser_tx.send(pr_mes);
|
let _ = self.render_tx.send(rd_mes).await;
|
||||||
let _ = self.exec_tx.send(exec_mes);
|
let _ = self.parser_tx.send(pr_mes).await;
|
||||||
|
let _ = self.exec_tx.send(exec_mes).await;
|
||||||
|
let _ = self.node_tx.send(node_mes).await;
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
@ -78,7 +86,7 @@ impl WatcherBuilder {
|
|||||||
Self::default()
|
Self::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn addr(mut self, addr: Option<String>) -> Self {
|
pub fn addr(mut self, addr: Option<SocketAddr>) -> Self {
|
||||||
self.addr = addr;
|
self.addr = addr;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -88,11 +96,16 @@ impl WatcherBuilder {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start(self) -> Watcher {
|
pub async fn log(render_tx: &mpsc::Sender<RenderCommand>, msg: String) -> Result<(), mpsc::error::SendError<RenderCommand>> {
|
||||||
|
let rendermsg = RenderCommand::RenderStringToPane { str: msg, pane: RenderPane::CliOutput };
|
||||||
|
render_tx.send(rendermsg).await
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub async fn start(self) -> Watcher {
|
||||||
let (render_tx, render_rx) = mpsc::channel::<RenderCommand>(100);
|
let (render_tx, render_rx) = mpsc::channel::<RenderCommand>(100);
|
||||||
let (parser_tx, parser_rx) = mpsc::channel::<ParserCommand>(100);
|
let (parser_tx, parser_rx) = mpsc::channel::<ParserCommand>(100);
|
||||||
let (exec_tx, exec_rx) = mpsc::channel::<ExecutorCommand>(100);
|
let (exec_tx, exec_rx) = mpsc::channel::<ExecutorCommand>(100);
|
||||||
let (node_tx, node_rx) = mpsc::channel::<NodeCommand>(100);
|
|
||||||
|
|
||||||
let mut terminal = ratatui::init();
|
let mut terminal = ratatui::init();
|
||||||
let render_handle = tokio::spawn({
|
let render_handle = tokio::spawn({
|
||||||
@ -100,6 +113,14 @@ impl WatcherBuilder {
|
|||||||
let _ = Renderer::new(render_rx, RenderLayoutKind::Cli).run(&mut terminal).await;
|
let _ = Renderer::new(render_rx, RenderLayoutKind::Cli).run(&mut terminal).await;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
let _ = Self::log(&render_tx, msg!(INFO, "Started Renderer")).await;
|
||||||
|
|
||||||
|
let blocks = self.seed_file
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|path| std::fs::read_to_string(path).ok())
|
||||||
|
.and_then(|content| serde_json::from_str(&content).ok());
|
||||||
|
let mut node = NativeNode::new(self.addr.clone(), blocks, exec_tx.clone());
|
||||||
|
let _ = Self::log(&render_tx, msg!(INFO, "Build Node"));
|
||||||
|
|
||||||
let parser_handle = tokio::spawn({
|
let parser_handle = tokio::spawn({
|
||||||
let exec_tx = exec_tx.clone();
|
let exec_tx = exec_tx.clone();
|
||||||
@ -108,27 +129,28 @@ impl WatcherBuilder {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let _ = Self::log(&render_tx, msg!(INFO, "Started Parser")).await;
|
||||||
|
|
||||||
let executor_handle = tokio::spawn({
|
let executor_handle = tokio::spawn({
|
||||||
let rend_tx = render_tx.clone();
|
let rend_tx = render_tx.clone();
|
||||||
let node_tx = node_tx.clone();
|
let node_tx = node.tx();
|
||||||
async move {
|
async move {
|
||||||
let _ = Executor::new(rend_tx, node_tx, exec_rx).run().await;
|
let _ = Executor::new(rend_tx, node_tx, exec_rx).run().await;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let blocks = self.seed_file
|
let _ = Self::log(&render_tx, msg!(INFO, "Started Executor")).await;
|
||||||
.as_ref()
|
|
||||||
.and_then(|path| std::fs::read_to_string(path).ok())
|
|
||||||
.and_then(|content| serde_json::from_str(&content).ok());
|
|
||||||
|
|
||||||
|
let node_tx = node.tx();
|
||||||
|
|
||||||
let node_handle = tokio::spawn({
|
let node_handle = tokio::spawn({
|
||||||
let exec_tx = exec_tx.clone();
|
|
||||||
async move {
|
async move {
|
||||||
let _ = NativeNode::new(self.addr.clone(), blocks, exec_tx, node_rx);
|
node.run_native().await;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let _ = Self::log(&render_tx, msg!(INFO, "Started Node")).await;
|
||||||
|
|
||||||
Watcher {
|
Watcher {
|
||||||
render_tx,
|
render_tx,
|
||||||
node_tx,
|
node_tx,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user