use futures::{SinkExt, StreamExt};
use coin::block::*;
use coin::user::*;
use coin::frametype::*;
use std::collections::HashMap;
use std::fs;
use tokio_tungstenite::{connect_async, tungstenite, tungstenite::protocol::Message};
use tungstenite::{http::{Method, Request}, client::*};
use url::Url;
use bincode::{serialize, deserialize};
use bytes::Bytes;
#[tokio::main]
async fn main() {
println!("Spender go brrrrrrrrrr");
let url = format!("ws://{SERVER_IP}:{PORT}");
let ws_stream = connect_async(url.as_str().into_client_request().unwrap()).await.unwrap().0;
let (mut write, mut read) = ws_stream.split();
let get_version_msg = serialize(&ClientFrame::GetVersion).unwrap();
write.send(Message::Binary(Bytes::from(get_version_msg))).await.unwrap();
if let Some(Ok(Message::Binary(response))) = read.next().await {
if let Ok(ServerFrame::Version(version)) = deserialize(&response) {
println!("Server version: {}", version);
}
}
let get_blockchain_msg = serialize(&ClientFrame::GetBlockchain).unwrap();
write.send(Message::Binary(Bytes::from(get_blockchain_msg))).await.unwrap();
let mut local_state = match fs::read("state.bin") {
Ok(serialized) => bincode::deserialize(&serialized).unwrap_or_else(|_| {
State::with_genesis_block()
}),
Err(_) => State::with_genesis_block(),
};
let mut blockchain = Vec::new();
while let Some(Ok(Message::Binary(response))) = read.next().await {
if let Ok(ServerFrame::BlockChain(data)) = deserialize(&response) {
blockchain = data;
break;
}
};
let mut network_state = State {
blocks: blockchain,
utxo_set: HashMap::new(),
old_utxo_set: HashMap::new(),
};
let mut state = if network_state.calc_total_work() > local_state.calc_total_work() &&
network_state.verify_all_and_update().is_ok() {
let serialized = bincode::serialize(&network_state).expect("Error serializing");
fs::write("state.bin", serialized).expect("Error writing to file");
network_state
} else {
local_state.verify_all_and_update().expect("Local state is invalid");
local_state
};
let (signing, verifying) = keys_from_str(&fs::read_to_string("private_key.txt").unwrap());
let mut new_block = Block::new();
let user = User::random();
const NUM_TX: u64 = 20;
for _ in 0..NUM_TX {
new_block.transact(&mut state.utxo_set, &signing, &user.verifying, 5).unwrap();
}
new_block.prev_hash = state.blocks.last().unwrap().get_hash();
println!("Block successfully verified!");
println!("Submitting {NUM_TX} test transactions");
let tx_frame_msg = serialize(&ClientFrame::TxFrame(new_block.txs.clone())).unwrap();
write.send(Message::Binary(Bytes::from(tx_frame_msg))).await.unwrap();
println!("Sent");
}