Starting to modify things into container structs

This commit is contained in:
Dave Hrycyszyn
2024-06-07 17:03:05 +01:00
parent b1f5d2b75a
commit a81d1f913a
5 changed files with 100 additions and 55 deletions

View File

@@ -15,8 +15,8 @@ use crate::keys;
#[add_crdt_fields] #[add_crdt_fields]
#[derive(Clone, CrdtNode, Serialize, Deserialize)] #[derive(Clone, CrdtNode, Serialize, Deserialize)]
pub(crate) struct CrdtList { pub(crate) struct TransactionList {
pub(crate) list: ListCrdt<Transaction>, // switch to Transaction as soon as char is working pub(crate) list: ListCrdt<Transaction>,
} }
/// A fake Transaction struct we can use as a simulated payload /// A fake Transaction struct we can use as a simulated payload
@@ -28,33 +28,33 @@ pub(crate) struct Transaction {
amount: f64, amount: f64,
} }
pub(crate) fn new(side_dir: PathBuf) -> (BaseCrdt<CrdtList>, Ed25519KeyPair) { pub(crate) fn new(side_dir: PathBuf) -> (BaseCrdt<TransactionList>, Ed25519KeyPair) {
let keys = keys::load_from_file(side_dir); let keys = keys::load_from_file(side_dir);
let bft_crdt = BaseCrdt::<CrdtList>::new(&keys); let bft_crdt = BaseCrdt::<TransactionList>::new(&keys);
println!("Author is {}", keys.public().to_string()); println!("Author is {}", keys.public().to_string());
(bft_crdt, keys) (bft_crdt, keys)
} }
pub(crate) fn create( pub(crate) fn create(
bft_crdt: &mut BaseCrdt<CrdtList>, bft_crdt: &mut BaseCrdt<TransactionList>,
keys: &Ed25519KeyPair, keys: &Ed25519KeyPair,
) -> bft_json_crdt::json_crdt::SignedOp { ) -> bft_json_crdt::json_crdt::SignedOp {
// generate a placeholder transaction // generate a placeholder transaction
let transaction = generate_transaction(keys.public().to_string()); let transaction = fake_transaction(keys.public().to_string());
// next job is to keep adding to this guy // next job is to keep adding to this guy
let next = bft_crdt.doc.list.ops.len(); let last = bft_crdt.doc.list.ops.last().expect("couldn't find last op");
let signed_op = bft_crdt let signed_op = bft_crdt
.doc .doc
.list .list
.insert_idx(next - 1, transaction.clone()) .insert(last.id, transaction.clone())
.sign(&keys); .sign(&keys);
signed_op signed_op
} }
fn generate_transaction(pubkey: String) -> Value { fn fake_transaction(from_pubkey: String) -> Value {
json!({ json!({
"from": pubkey, "from": from_pubkey,
"to": "Bob", "to": "Bob",
"amount": 1 "amount": 1
}) })

View File

@@ -1,9 +1,14 @@
use bft_json_crdt::json_crdt::BaseCrdt;
use cli::{parse_args, Commands}; use cli::{parse_args, Commands};
use list_transaction_crdt::TransactionList;
use node::SideNode;
use websocket::WebSocketClient;
pub(crate) mod cli; pub(crate) mod cli;
pub(crate) mod init; pub(crate) mod init;
pub(crate) mod keys; pub(crate) mod keys;
pub(crate) mod list_transaction_crdt; pub(crate) mod list_transaction_crdt;
pub(crate) mod node;
pub(crate) mod utils; pub(crate) mod utils;
pub(crate) mod websocket; pub(crate) mod websocket;
@@ -17,20 +22,23 @@ async fn main() {
name: name.to_string(), name: name.to_string(),
}; };
let _ = init::init(home(name), config); let _ = init::init(utils::home(name), config);
} }
Some(Commands::Run { name }) => { Some(Commands::Run { name }) => {
let side_dir = home(name); let (crdt, websocket_client) = setup(name);
let (mut bft_crdt, keys) = list_transaction_crdt::new(side_dir); let side_node = &mut SideNode::new(websocket_client, crdt, name.to_owned());
websocket::start(keys, &mut bft_crdt).await; side_node.start().await;
} }
None => println!("No command provided. Exiting. See --help for more information."), None => println!("No command provided. Exiting. See --help for more information."),
} }
} }
fn home(name: &String) -> std::path::PathBuf { fn setup(name: &String) -> (BaseCrdt<TransactionList>, WebSocketClient) {
let mut path = dirs::home_dir().unwrap(); let side_dir = utils::home(name);
path.push(".side"); let keys = keys::load_from_file(side_dir);
path.push(name);
path let websocket_client = WebSocketClient::new();
let crdt = BaseCrdt::<TransactionList>::new(&keys);
(crdt, websocket_client)
} }

31
side-node/src/node.rs Normal file
View File

@@ -0,0 +1,31 @@
use bft_json_crdt::json_crdt::BaseCrdt;
use fastcrypto::ed25519::Ed25519KeyPair;
use crate::{keys, list_transaction_crdt::TransactionList, utils, websocket::WebSocketClient};
pub(crate) struct SideNode {
crdt: BaseCrdt<TransactionList>,
keys: Ed25519KeyPair,
websocket_client: WebSocketClient,
}
impl SideNode {
pub(crate) fn new(
websocket_client: WebSocketClient,
crdt: BaseCrdt<TransactionList>,
name: String,
) -> Self {
let side_dir = utils::home(&name);
let keys = keys::load_from_file(side_dir);
Self {
crdt,
keys,
websocket_client,
}
}
pub(crate) async fn start(&mut self) {
self.websocket_client.start().await;
}
}

View File

@@ -3,7 +3,7 @@ use std::path::PathBuf;
pub(crate) const KEY_FILE: &str = "keys.pem"; pub(crate) const KEY_FILE: &str = "keys.pem";
pub(crate) const CONFIG_FILE: &str = "config.toml"; pub(crate) const CONFIG_FILE: &str = "config.toml";
/// Returns the path to the key file for this host OS. /// Returns the path to the key file and config for this host OS.
pub(crate) fn side_paths(prefix: PathBuf) -> (PathBuf, PathBuf) { pub(crate) fn side_paths(prefix: PathBuf) -> (PathBuf, PathBuf) {
let mut key_path = prefix.clone(); let mut key_path = prefix.clone();
key_path.push(KEY_FILE); key_path.push(KEY_FILE);
@@ -13,3 +13,10 @@ pub(crate) fn side_paths(prefix: PathBuf) -> (PathBuf, PathBuf) {
(key_path, config_path) (key_path, config_path)
} }
pub(crate) fn home(name: &String) -> std::path::PathBuf {
let mut path = dirs::home_dir().unwrap();
path.push(".side");
path.push(name);
path
}

View File

@@ -1,28 +1,47 @@
/*
loop {
let author = general_purpose::STANDARD.encode(&incoming_operation.author());
bft_crdt.apply(incoming_operation.clone());
}
*/
use async_trait::async_trait; use async_trait::async_trait;
use bft_json_crdt::json_crdt::BaseCrdt;
use ezsockets::ClientConfig; use ezsockets::ClientConfig;
use fastcrypto::ed25519::Ed25519KeyPair;
use std::io::BufRead; use std::io::BufRead;
use crate::list_transaction_crdt::{self, CrdtList}; pub(crate) struct WebSocketClient {}
struct Client {} impl WebSocketClient {
pub(crate) fn new() -> Self {
Self {}
}
/// Start the websocket client
pub(crate) async fn start(&mut self) {
tracing_subscriber::fmt::init();
let config = ClientConfig::new("ws://localhost:8080/websocket");
let (handle, future) = ezsockets::connect(|_client| WebSocketClient {}, config).await;
tokio::spawn(async move {
future.await.unwrap();
});
let stdin = std::io::stdin();
let lines = stdin.lock().lines();
for line in lines {
let line = line.unwrap();
let signed_op = if let "exit" = line.as_str() {
break;
} else {
// list_transaction_crdt::create(bft_crdt, &keys)
};
tracing::info!("sending {:?}", signed_op);
let json = serde_json::to_string(&signed_op).unwrap();
handle.text(json).unwrap();
}
}
}
#[async_trait] #[async_trait]
impl ezsockets::ClientExt for Client { impl ezsockets::ClientExt for WebSocketClient {
type Call = (); type Call = ();
async fn on_text(&mut self, text: String) -> Result<(), ezsockets::Error> { async fn on_text(&mut self, text: String) -> Result<(), ezsockets::Error> {
tracing::info!("received message: {text}"); tracing::info!("received message: {text}");
// let incoming: bft_json_crdt::json_crdt::SignedOp = serde_json::from_str(&text).unwrap();
// let author = base64::engine::general_purpose::STANDARD.encode(&incoming.author());
// self.bft_crdt.apply(incoming.clone());
Ok(()) Ok(())
} }
@@ -37,24 +56,4 @@ impl ezsockets::ClientExt for Client {
} }
} }
pub(crate) async fn start(keys: Ed25519KeyPair, bft_crdt: &mut BaseCrdt<CrdtList>) { // pub(crate) async fn start(self, keys: Ed25519KeyPair, bft_crdt: &mut BaseCrdt<CrdtList>) {}
tracing_subscriber::fmt::init();
let config = ClientConfig::new("ws://localhost:8080/websocket");
let (handle, future) = ezsockets::connect(|_client| Client {}, config).await;
tokio::spawn(async move {
future.await.unwrap();
});
let stdin = std::io::stdin();
let lines = stdin.lock().lines();
for line in lines {
let line = line.unwrap();
let signed_op = if let "exit" = line.as_str() {
break;
} else {
list_transaction_crdt::create(bft_crdt, &keys)
};
tracing::info!("sending {:?}", signed_op);
let json = serde_json::to_string(&signed_op).unwrap();
handle.text(json).unwrap();
}
}