Skip to content

Commit

Permalink
Merge pull request #13 from bjohnson5/ldk-model
Browse files Browse the repository at this point in the history
Ldk model
  • Loading branch information
bjohnson5 authored Oct 29, 2024
2 parents f423d10 + b7c0180 commit c783ab2
Show file tree
Hide file tree
Showing 22 changed files with 941 additions and 31 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ tar xzf bitcoin-25.0-x86_64-linux-gnu.tar.gz
sudo install -m 0755 -o root -g root -t /usr/local/bin bitcoin-25.0/bin/*
```

### Install utils
```bash
sudo apt install bc
sudo apt install jq
```

### Install Rust
```bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
Expand Down
4 changes: 4 additions & 0 deletions blast_cli/src/blast_cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::load::*;
use crate::configure::*;
use crate::run::*;

// The BLAST CLI, which is comprised of 4 tabs
pub struct BlastCli {
pub new: NewTab,
pub load: LoadTab,
Expand All @@ -20,6 +21,7 @@ impl BlastCli {
// Create the blast core object
let blast = Blast::new();

// Get a list of the available models
let mut model_list: Vec<Model> = Vec::new();
match blast.get_available_models() {
Ok(models) => {
Expand All @@ -30,6 +32,7 @@ impl BlastCli {
Err(_) => {}
}

// Get a list of saved sims that can be loaded
let mut sim_list: Vec<String> = Vec::new();
match blast.get_available_sims() {
Ok(sims) => {
Expand All @@ -40,6 +43,7 @@ impl BlastCli {
Err(_) => {}
}

// Create the tabs
let nt = NewTab{models: StatefulList::with_items(model_list)};
let lt = LoadTab{sims: StatefulList::with_items(sim_list)};
let ct = ConfigureTab::new();
Expand Down
11 changes: 10 additions & 1 deletion blast_cli/src/configure.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
// TUI libraries
use ratatui::{
crossterm::event::{KeyCode, KeyEvent, KeyEventKind},
prelude::*,
widgets::*,
};

// Extra Dependencies
use textwrap;

// BLAST libraries
use crate::shared::*;

// The sections of the Configure page
#[derive(PartialEq,Clone)]
pub enum ConfigureSection {
Command,
Expand All @@ -16,6 +20,7 @@ pub enum ConfigureSection {
Activity
}

// The Configure Tab structure
pub struct ConfigureTab {
pub input: String,
pub history: Vec<String>,
Expand All @@ -28,6 +33,7 @@ pub struct ConfigureTab {
pub current_section: ConfigureSection
}

// The Configure Tab is a window that displays a CLI and the current state of the test network
impl ConfigureTab {
pub fn new() -> Self {
Self {
Expand Down Expand Up @@ -192,10 +198,12 @@ impl BlastTab for ConfigureTab {
frame.render_widget(messages, messages_area);
}

/// This is called when the configure tab is first displayed
fn init(&mut self) {
self.current_section = ConfigureSection::Command;
}

/// This is called when the configure tab is closed
fn close(&mut self) {
self.messages.clear();
self.input.clear();
Expand All @@ -206,6 +214,7 @@ impl BlastTab for ConfigureTab {
self.history_index = 0;
}

/// This is called when a key is pressed while on the configure tab
fn process(&mut self, key: KeyEvent) -> ProcessResult {
if key.kind == KeyEventKind::Press {
match key.code {
Expand Down Expand Up @@ -302,7 +311,7 @@ impl BlastTab for ConfigureTab {
KeyCode::Down => {
match self.current_section {
ConfigureSection::Command => {
if self.history_index <= self.history.len() - 1 {
if self.history.len() > 0 && self.history_index <= self.history.len() - 1 {
self.history_index += 1;
self.input = self.history.get(self.history_index).unwrap_or(&String::from("")).to_string();
self.character_index = self.input.len();
Expand Down
25 changes: 19 additions & 6 deletions blast_cli/src/load.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,34 @@
// TUI libraries
use ratatui::{
crossterm::event::{KeyCode, KeyEvent},
prelude::*,
widgets::*,
};

// BLAST libraries
use crate::shared::*;

// The Load Tab structure
pub struct LoadTab {
pub sims: StatefulList<String>
}

// The Load Tab is a window that displays the saved simulations and lets the user select one to load
impl BlastTab for LoadTab {
/// Draw the tab
fn draw(&mut self, frame: &mut Frame, area: Rect) {
let layout = Layout::new(
Direction::Vertical,
[Constraint::Percentage(25), Constraint::Percentage(5), Constraint::Percentage(70)],
)
.split(area);


// layout[0] The top of the window show the BLAST banner
frame.render_widget(
Paragraph::new(BANNER), layout[0]
);

// layout[1] The help message
let msg = vec![
"Press ".into(),
"q".bold(),
Expand All @@ -30,11 +41,8 @@ impl BlastTab for LoadTab {
let text = Text::from(Line::from(msg)).patch_style(Style::default());
let help_message = Paragraph::new(text);
frame.render_widget(help_message, layout[1]);

frame.render_widget(
Paragraph::new(BANNER), layout[0]
);


// layout[2] The list of simulations
let tasks: Vec<ListItem> = self
.sims
.items
Expand All @@ -50,14 +58,17 @@ impl BlastTab for LoadTab {
frame.render_stateful_widget(tasks, layout[2], &mut self.sims.state);
}

/// This is called when the load tab is first displayed
fn init(&mut self) {
self.sims.next();
}

/// This is called when the load tab is closing
fn close(&mut self) {
self.sims.clear();
}

/// This is called when a key is pressed while on the load tab
fn process(&mut self, key: KeyEvent) -> ProcessResult {
match key.code {
// Scroll the list of simulations
Expand All @@ -68,9 +79,11 @@ impl BlastTab for LoadTab {
KeyCode::Up => {
self.sims.previous();
}
// Load the selected simulation
KeyCode::Enter => {
return ProcessResult::LoadNetwork(self.sims.items[self.sims.state.selected().unwrap()].clone());
}
// Ignore all other keys
_ => {}
}

Expand Down
29 changes: 20 additions & 9 deletions blast_cli/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// Standard libraries
use std::{error::Error, io, time::Instant, time::Duration};
use std::collections::HashMap;
use std::sync::atomic::{AtomicBool, Ordering};
Expand All @@ -7,12 +8,14 @@ use std::fs::File;
use std::path::PathBuf;
use std::env;

// Extra Dependencies
use simplelog::WriteLogger;
use simplelog::Config;
use log::LevelFilter;
use tokio::task::JoinSet;
use anyhow::Error as AnyError;

// TUI libraries
use ratatui::{
crossterm::{
event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode},
Expand All @@ -23,6 +26,7 @@ use ratatui::{
widgets::*,
};

// BLAST libraries
mod shared;
mod new;
mod load;
Expand All @@ -49,18 +53,18 @@ async fn main() -> Result<(), Box<dyn Error>> {
File::create(folder_path).unwrap(),
);

// setup terminal
// Setup terminal
enable_raw_mode()?;
let mut stdout = io::stdout();
execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;
let backend = CrosstermBackend::new(stdout);
let mut terminal = Terminal::new(backend)?;

// create app and run it
// Create app and run it
let cli = BlastCli::new();
let res = run(&mut terminal, cli).await;

// restore terminal
// Restore terminal
disable_raw_mode()?;
execute!(
terminal.backend_mut(),
Expand Down Expand Up @@ -170,7 +174,9 @@ async fn run<B: Backend>(terminal: &mut Terminal<B>, mut blast_cli: BlastCli) ->
running.store(true, Ordering::SeqCst);
let mut m = HashMap::new();
for model in models {
m.insert(model.name.clone(), model.num_nodes);
if model.num_nodes > 0 {
m.insert(model.name.clone(), model.num_nodes);
}
}
match blast_cli.blast.create_network("test", m, running.clone()).await {
Ok(mut m) => {
Expand Down Expand Up @@ -549,7 +555,8 @@ async fn run_command(blast: &mut blast_core::Blast, cmd: String) -> Vec<String>
match blast.open_channel(source, dest, amount, push, chan_id, true).await {
Ok(_) => {},
Err(e) => {
println!("{}", format!("Unable to open channel: {}", e));
let msg = format!("Unable to open channel: {}", e);
output.push(msg);
}
}
},
Expand All @@ -563,7 +570,8 @@ async fn run_command(blast: &mut blast_core::Blast, cmd: String) -> Vec<String>
match blast.close_channel(source, chan_id).await {
Ok(_) => {},
Err(e) => {
println!("{}", format!("Unable to open channel: {}", e));
let msg = format!("Unable to open channel: {}", e);
output.push(msg);
}
}
},
Expand All @@ -573,7 +581,8 @@ async fn run_command(blast: &mut blast_core::Blast, cmd: String) -> Vec<String>
match blast.connect_peer(source, dest).await {
Ok(_) => {},
Err(e) => {
println!("{}", format!("Unable to connect peers: {}", e));
let msg = format!("Unable to connect peers: {}", e);
output.push(msg);
}
}
},
Expand All @@ -583,7 +592,8 @@ async fn run_command(blast: &mut blast_core::Blast, cmd: String) -> Vec<String>
match blast.disconnect_peer(source, dest).await {
Ok(_) => {},
Err(e) => {
println!("{}", format!("Unable to disconnect peers: {}", e));
let msg = format!("Unable to disconnect peers: {}", e);
output.push(msg);
}
}
},
Expand All @@ -592,7 +602,8 @@ async fn run_command(blast: &mut blast_core::Blast, cmd: String) -> Vec<String>
match blast.fund_node(source, true).await {
Ok(_) => {},
Err(e) => {
println!("{}", format!("Unable to fund node: {}", e));
let msg = format!("Unable to fund node: {}", e);
output.push(msg);
}
}
},
Expand Down
25 changes: 19 additions & 6 deletions blast_cli/src/new.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,34 @@
// TUI libraries
use ratatui::{
crossterm::event::{KeyCode, KeyEvent},
prelude::*,
widgets::*,
};

// BLAST libraries
use crate::shared::*;

// The New Tab structure
pub struct NewTab {
pub models: StatefulList<Model>
}

// The New Tab is a window that displays the available models and lets the user select the number of nodes for each
impl BlastTab for NewTab {
/// Draw the tab
fn draw(&mut self, frame: &mut Frame, area: Rect) {
let layout = Layout::new(
Direction::Vertical,
[Constraint::Percentage(25), Constraint::Percentage(5), Constraint::Percentage(70)],
)
.split(area);


// layout[0] The top of the window show the BLAST banner
frame.render_widget(
Paragraph::new(BANNER), layout[0]
);

// layout[1] The help message
let msg = vec![
"Press ".into(),
"q".bold(),
Expand All @@ -30,11 +41,8 @@ impl BlastTab for NewTab {
let text = Text::from(Line::from(msg)).patch_style(Style::default());
let help_message = Paragraph::new(text);
frame.render_widget(help_message, layout[1]);

frame.render_widget(
Paragraph::new(BANNER), layout[0]
);


// layout[2] The list of available models
let tasks: Vec<ListItem> = self
.models
.items
Expand All @@ -50,14 +58,17 @@ impl BlastTab for NewTab {
frame.render_stateful_widget(tasks, layout[2], &mut self.models.state);
}

/// This is called when the new tab is first displayed
fn init(&mut self) {
self.models.next();
}

/// This is called when the new tab is closing
fn close(&mut self) {
self.models.clear();
}

/// This is called when a key is pressed while on the new tab
fn process(&mut self, key: KeyEvent) -> ProcessResult {
match key.code {
// Scroll the list of models
Expand All @@ -83,9 +94,11 @@ impl BlastTab for NewTab {
}
}
}
// Start the network
KeyCode::Enter => {
return ProcessResult::StartNetwork(self.models.items.clone());
}
// Ignore all other keys
_ => {}
}

Expand Down
Loading

0 comments on commit c783ab2

Please sign in to comment.