diff --git a/side-node/src/main.rs b/side-node/src/main.rs index f787311..1cd37b1 100644 --- a/side-node/src/main.rs +++ b/side-node/src/main.rs @@ -1,7 +1,11 @@ +use bft_json_crdt::keypair::Ed25519KeyPair; +use bft_json_crdt::{json_crdt::BaseCrdt, keypair::make_keypair}; use cli::{parse_args, Commands}; +use types::ListExample; pub(crate) mod cli; pub(crate) mod init; +pub(crate) mod types; pub(crate) mod websocket; #[tokio::main] @@ -13,8 +17,15 @@ async fn main() { init::init(); } Some(Commands::Run {}) => { - websocket::start().await.unwrap(); + let (mut bft_crdt, keys) = setup_crdt(); + websocket::start(keys, &mut bft_crdt).await.unwrap(); } None => println!("No command provided. Exiting. See --help for more information."), } } + +fn setup_crdt() -> (BaseCrdt, Ed25519KeyPair) { + let keys = make_keypair(); + let bft_crdt = BaseCrdt::::new(&keys); + (bft_crdt, keys) +} diff --git a/side-node/src/types.rs b/side-node/src/types.rs new file mode 100644 index 0000000..1cdddd9 --- /dev/null +++ b/side-node/src/types.rs @@ -0,0 +1,23 @@ +use bft_crdt_derive::add_crdt_fields; + +use bft_json_crdt::{ + json_crdt::{CrdtNode, IntoCrdtNode}, + list_crdt::ListCrdt, +}; + +use serde::{Deserialize, Serialize}; + +#[add_crdt_fields] +#[derive(Clone, CrdtNode, Serialize, Deserialize)] +pub(crate) struct ListExample { + pub(crate) list: ListCrdt, // switch to Transaction as soon as char is working +} + +/// A fake Transaction struct we can use as a simulated payload +#[add_crdt_fields] +#[derive(Clone, CrdtNode, Serialize, Deserialize)] +pub(crate) struct Transaction { + from: String, + to: String, + amount: f64, +} diff --git a/side-node/src/websocket/mod.rs b/side-node/src/websocket/mod.rs index 7871c03..3c64af6 100644 --- a/side-node/src/websocket/mod.rs +++ b/side-node/src/websocket/mod.rs @@ -1,37 +1,30 @@ -use bft_crdt_derive::add_crdt_fields; +use crate::types::ListExample; use bft_json_crdt::json_crdt::SignedOp; -use bft_json_crdt::keypair::{Ed25519KeyPair, KeyPair}; -use bft_json_crdt::{ - json_crdt::{BaseCrdt, CrdtNode, IntoCrdtNode}, - keypair::make_keypair, - list_crdt::ListCrdt, - // op::ROOT_ID, -}; -use serde::{Deserialize, Serialize}; -use serde_json::{json, Value}; +use bft_json_crdt::json_crdt::{BaseCrdt, CrdtNode}; +use bft_json_crdt::keypair::Ed25519KeyPair; +use send_transaction::send_a_transaction; use tokio::time; -// use tokio::time::{self}; use websockets::WebSocket; +pub(crate) mod send_transaction; + /// Starts a websocket and periodically sends a BFT-CRDT message to the websocket server -pub(crate) async fn start() -> Result<(), websockets::WebSocketError> { +pub(crate) async fn start( + keys: Ed25519KeyPair, + bft_crdt: &mut BaseCrdt, +) -> Result<(), websockets::WebSocketError> { println!("connecting to websocket at ws://127.0.0.1:8080/"); let mut ws = WebSocket::connect("ws://127.0.0.1:8080/").await?; - // set up a new BFT-CRDT - let keys = make_keypair(); - let mut bft_crdt = BaseCrdt::::new(&keys); - println!("Generated a new CRDT with public key: {}", keys.public()); - let mut interval = every_two_seconds(); let mut count = 0; loop { - let _ = send_a_transaction(count, &mut bft_crdt, &mut ws, &keys).await; + let _ = send_a_transaction(count, bft_crdt, &mut ws, &keys).await; let msg = ws.receive().await?; println!("Received: {:?}", msg); - // deserialize the received Frame into a string + // deserialize the received websocket Frame into a string let msg = msg.into_text().unwrap().0; // deserialize the message into a Transaction struct @@ -49,49 +42,3 @@ pub(crate) async fn start() -> Result<(), websockets::WebSocketError> { fn every_two_seconds() -> time::Interval { time::interval(time::Duration::from_secs(2)) } - -#[add_crdt_fields] -#[derive(Clone, CrdtNode, Serialize, Deserialize)] -struct ListExample { - list: ListCrdt, // switch to Transaction as soon as char is working -} - -/// A fake Transaction struct we can use as a simulated payload -#[add_crdt_fields] -#[derive(Clone, CrdtNode, Serialize, Deserialize)] -struct Transaction { - from: String, - to: String, - amount: f64, -} - -fn generate_transaction(count: u32) -> Value { - json!({ - "from": "Alice", - "to": "Bob", - "amount": count - }) -} - -async fn send_a_transaction( - count: u32, - bft_crdt: &mut BaseCrdt, - ws: &mut WebSocket, - keys: &Ed25519KeyPair, -) -> Result<(), websockets::WebSocketError> { - // generate a placeholder transaction - let transaction = generate_transaction(count); - - // next job is to keep adding to this guy - let signed_op = bft_crdt - .doc - .list - .insert_idx(0, transaction.clone()) - .sign(&keys); - println!("SignedOp being sent is: {:?}", signed_op); - - println!("Sending: {:?}", signed_op); - Ok(ws - .send_text(serde_json::to_string(&signed_op).unwrap()) - .await?) -} diff --git a/side-node/src/websocket/send_transaction.rs b/side-node/src/websocket/send_transaction.rs new file mode 100644 index 0000000..7d9118c --- /dev/null +++ b/side-node/src/websocket/send_transaction.rs @@ -0,0 +1,36 @@ +use bft_json_crdt::{json_crdt::BaseCrdt, keypair::Ed25519KeyPair}; +use serde_json::{json, Value}; +use websockets::WebSocket; + +use crate::types::ListExample; + +pub(crate) async fn send_a_transaction( + count: u32, + bft_crdt: &mut BaseCrdt, + ws: &mut WebSocket, + keys: &Ed25519KeyPair, +) -> Result<(), websockets::WebSocketError> { + // generate a placeholder transaction + let transaction = generate_transaction(count); + + // next job is to keep adding to this guy + let signed_op = bft_crdt + .doc + .list + .insert_idx(0, transaction.clone()) + .sign(&keys); + println!("SignedOp being sent is: {:?}", signed_op); + + println!("Sending: {:?}", signed_op); + Ok(ws + .send_text(serde_json::to_string(&signed_op).unwrap()) + .await?) +} + +fn generate_transaction(count: u32) -> Value { + json!({ + "from": "Alice", + "to": "Bob", + "amount": count + }) +}