feat: ✨ server side basics
This commit is contained in:
parent
5111196588
commit
7f31e76881
11 changed files with 266 additions and 440 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1 +1,4 @@
|
|||
/target
|
||||
/.vscode
|
||||
|
||||
Cargo.lock
|
415
Cargo.lock
generated
415
Cargo.lock
generated
|
@ -1,415 +0,0 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "android-tzdata"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
|
||||
|
||||
[[package]]
|
||||
name = "android_system_properties"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.98"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
|
||||
dependencies = [
|
||||
"android-tzdata",
|
||||
"iana-time-zone",
|
||||
"js-sys",
|
||||
"num-traits",
|
||||
"wasm-bindgen",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141"
|
||||
dependencies = [
|
||||
"android_system_properties",
|
||||
"core-foundation-sys",
|
||||
"iana-time-zone-haiku",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"windows-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone-haiku"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "keccak"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654"
|
||||
dependencies = [
|
||||
"cpufeatures",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.155"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust-blockchain"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.202"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.202"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.117"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha3"
|
||||
version = "0.10.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60"
|
||||
dependencies = [
|
||||
"digest",
|
||||
"keccak",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.65"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2863d96a84c6439701d7a38f9de935ec562c8832cc55d1dde0f513b52fad106"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
|
|
@ -10,3 +10,4 @@ chrono = "0.4.38"
|
|||
serde = { version = "1.0.202", features = ["derive"] }
|
||||
serde_json = "1.0.117"
|
||||
sha3 = "0.10.8"
|
||||
tokio = { version = "1.37.0", features = ["full"] }
|
||||
|
|
3
configs/server_config.txt
Normal file
3
configs/server_config.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
server_address:127.0.0.1
|
||||
port:2434
|
||||
difficulty:1
|
15
src/block.rs
15
src/block.rs
|
@ -3,6 +3,7 @@ use std::time::{Duration, Instant};
|
|||
use chrono::Utc;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sha3::{Digest, Sha3_512};
|
||||
use tokio::sync::broadcast::Sender;
|
||||
|
||||
use crate::blockchain::BlockChain;
|
||||
|
||||
|
@ -28,8 +29,14 @@ impl Block {
|
|||
format!("{:x}", hash)
|
||||
}
|
||||
|
||||
pub fn new(index: u64, data: String, previous_hash: String, instant: Instant) -> Self {
|
||||
Block {
|
||||
pub fn new(
|
||||
index: u64,
|
||||
data: String,
|
||||
previous_hash: String,
|
||||
instant: Instant,
|
||||
block_data_channel_sender: Sender<Block>,
|
||||
) -> Self {
|
||||
let block = Block {
|
||||
index,
|
||||
timestamp: Utc::now().timestamp_millis() as u64,
|
||||
data,
|
||||
|
@ -37,7 +44,9 @@ impl Block {
|
|||
previous_hash,
|
||||
hash: String::new(),
|
||||
hash_time_cost: instant.elapsed(),
|
||||
}
|
||||
};
|
||||
let _ = block_data_channel_sender.send(block.clone());
|
||||
block
|
||||
}
|
||||
|
||||
pub fn mine(&mut self, blockhain: BlockChain) -> Self {
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
use std::time::{Duration, Instant};
|
||||
|
||||
use chrono::Utc;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tokio::sync::broadcast::Sender;
|
||||
|
||||
use crate::block::Block;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct BlockChain {
|
||||
pub genesis_block: Block,
|
||||
pub chain: Vec<Block>,
|
||||
|
@ -32,12 +34,18 @@ impl BlockChain {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn add_block(&mut self, data: String, instant: Instant) {
|
||||
pub fn add_block(
|
||||
&mut self,
|
||||
data: String,
|
||||
instant: Instant,
|
||||
block_data_channel_sender: Sender<Block>,
|
||||
) {
|
||||
let new_block = Block::new(
|
||||
self.chain.len() as u64,
|
||||
data,
|
||||
self.chain[&self.chain.len() - 1].hash.clone(),
|
||||
instant,
|
||||
block_data_channel_sender,
|
||||
)
|
||||
.mine(self.clone());
|
||||
self.chain.push(new_block);
|
||||
|
|
15
src/lib.rs
15
src/lib.rs
|
@ -1,2 +1,17 @@
|
|||
use std::net::IpAddr;
|
||||
|
||||
pub mod block;
|
||||
pub mod blockchain;
|
||||
pub mod network;
|
||||
mod test;
|
||||
pub mod utils;
|
||||
|
||||
pub enum Runner {
|
||||
Server,
|
||||
Client,
|
||||
}
|
||||
pub struct ServerConfig {
|
||||
pub server_address: IpAddr,
|
||||
pub port: u16,
|
||||
pub difficulty: u8,
|
||||
}
|
||||
|
|
52
src/main.rs
52
src/main.rs
|
@ -1,24 +1,36 @@
|
|||
use std::time::Instant;
|
||||
use rust_blockchain::{
|
||||
blockchain::BlockChain,
|
||||
network::start_network,
|
||||
utils::{read_server_config, take_args},
|
||||
Runner,
|
||||
};
|
||||
use tokio::sync::broadcast;
|
||||
|
||||
use rust_blockchain::blockchain::BlockChain;
|
||||
|
||||
fn main() {
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
println!("Hello, world!");
|
||||
|
||||
let difficulty = 1;
|
||||
|
||||
let mut blockchain = BlockChain::new(difficulty);
|
||||
let instant = Instant::now();
|
||||
BlockChain::add_block(&mut blockchain, "T".to_string(), Instant::now());
|
||||
BlockChain::add_block(&mut blockchain, "a".to_string(), Instant::now());
|
||||
BlockChain::add_block(&mut blockchain, "h".to_string(), Instant::now());
|
||||
BlockChain::add_block(&mut blockchain, "i".to_string(), Instant::now());
|
||||
BlockChain::add_block(&mut blockchain, "n".to_string(), Instant::now());
|
||||
BlockChain::add_block(&mut blockchain, "l".to_string(), Instant::now());
|
||||
BlockChain::add_block(&mut blockchain, "i".to_string(), Instant::now());
|
||||
println!(
|
||||
"\t ⛏️⛏️⛏️ | Mined | ⛏️⛏️⛏️\n\n\tElapsed: {:?}\n\n{:#?}",
|
||||
instant.elapsed(),
|
||||
blockchain
|
||||
);
|
||||
match take_args() {
|
||||
Some(runner) => match runner {
|
||||
Runner::Server => server().await,
|
||||
Runner::Client => todo!(),
|
||||
},
|
||||
None => return,
|
||||
};
|
||||
}
|
||||
|
||||
async fn server() {
|
||||
let server_config = match read_server_config() {
|
||||
Some(server_config) => server_config,
|
||||
None => return,
|
||||
};
|
||||
|
||||
let blockchain = BlockChain::new(server_config.difficulty.into());
|
||||
let block_data_channel_sender = broadcast::channel(1).0;
|
||||
start_network(
|
||||
server_config,
|
||||
&blockchain,
|
||||
block_data_channel_sender.subscribe(),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
|
81
src/network.rs
Normal file
81
src/network.rs
Normal file
|
@ -0,0 +1,81 @@
|
|||
use tokio::{
|
||||
io::AsyncWriteExt,
|
||||
net::{TcpListener, TcpStream},
|
||||
sync::broadcast::Receiver,
|
||||
};
|
||||
|
||||
use crate::{block::Block, blockchain::BlockChain, ServerConfig};
|
||||
|
||||
pub async fn start_network(
|
||||
server_config: ServerConfig,
|
||||
blockchain: &BlockChain,
|
||||
block_data_channel_receiver: Receiver<Block>,
|
||||
) {
|
||||
let listener_socket = match TcpListener::bind(format!(
|
||||
"{}:{}",
|
||||
server_config.server_address, server_config.port
|
||||
))
|
||||
.await
|
||||
{
|
||||
Ok(listener_socket) => listener_socket,
|
||||
Err(_) => return,
|
||||
};
|
||||
|
||||
loop {
|
||||
match listener_socket.accept().await {
|
||||
Ok(connection) => {
|
||||
tokio::spawn(sync(
|
||||
connection.0,
|
||||
blockchain.clone(),
|
||||
block_data_channel_receiver.resubscribe(),
|
||||
));
|
||||
}
|
||||
Err(_) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn sync(
|
||||
tcp_stream: TcpStream,
|
||||
blockchain: BlockChain,
|
||||
block_data_channel_receiver: Receiver<Block>,
|
||||
) {
|
||||
let tcp_stream = send_blockchain(tcp_stream, blockchain).await;
|
||||
send_block(tcp_stream, block_data_channel_receiver).await;
|
||||
}
|
||||
|
||||
async fn send_blockchain(mut tcp_stream: TcpStream, blockchain: BlockChain) -> TcpStream {
|
||||
let blockchain_data = serde_json::json!({
|
||||
"blockchain": blockchain
|
||||
})
|
||||
.to_string();
|
||||
match tcp_stream.write_all(&blockchain_data.as_bytes()).await {
|
||||
Ok(_) => match tcp_stream.flush().await {
|
||||
Ok(_) => {}
|
||||
Err(_) => {}
|
||||
},
|
||||
Err(_) => {}
|
||||
}
|
||||
tcp_stream
|
||||
}
|
||||
|
||||
async fn send_block(mut tcp_stream: TcpStream, mut block_data_channel_receiver: Receiver<Block>) {
|
||||
loop {
|
||||
match block_data_channel_receiver.recv().await {
|
||||
Ok(block) => {
|
||||
let block_data = serde_json::json!({
|
||||
"block": block
|
||||
})
|
||||
.to_string();
|
||||
match tcp_stream.write_all(&block_data.as_bytes()).await {
|
||||
Ok(_) => match tcp_stream.flush().await {
|
||||
Ok(_) => {}
|
||||
Err(_) => {}
|
||||
},
|
||||
Err(_) => {}
|
||||
}
|
||||
}
|
||||
Err(_) => {}
|
||||
}
|
||||
}
|
||||
}
|
52
src/test.rs
Normal file
52
src/test.rs
Normal file
|
@ -0,0 +1,52 @@
|
|||
#[cfg(test)]
|
||||
use crate::blockchain::BlockChain;
|
||||
#[cfg(test)]
|
||||
use std::time::Duration;
|
||||
#[cfg(test)]
|
||||
use std::time::Instant;
|
||||
#[cfg(test)]
|
||||
use tokio::sync::broadcast::channel;
|
||||
|
||||
#[tokio::test]
|
||||
async fn create_blockchain() {
|
||||
let blockchain = BlockChain::new(1);
|
||||
assert_eq!(blockchain.difficulty, 1);
|
||||
assert_eq!(blockchain.genesis_block.data, "Tahinli");
|
||||
assert_eq!(blockchain.genesis_block.hash, "");
|
||||
assert_eq!(blockchain.genesis_block.index, 0);
|
||||
assert_eq!(blockchain.genesis_block.previous_hash, "");
|
||||
assert_eq!(blockchain.genesis_block.proof_of_work, 0);
|
||||
assert_eq!(
|
||||
blockchain.genesis_block.hash_time_cost,
|
||||
Duration::from_secs(0)
|
||||
);
|
||||
assert_eq!(blockchain.chain.len(), 1);
|
||||
assert_eq!(blockchain.chain[0].data, "Tahinli");
|
||||
assert_eq!(blockchain.chain[0].hash, "");
|
||||
assert_eq!(blockchain.chain[0].index, 0);
|
||||
assert_eq!(blockchain.chain[0].previous_hash, "");
|
||||
assert_eq!(blockchain.chain[0].proof_of_work, 0);
|
||||
assert_eq!(blockchain.chain[0].hash_time_cost, Duration::from_secs(0));
|
||||
}
|
||||
#[tokio::test]
|
||||
async fn create_block() {
|
||||
let instant = Instant::now();
|
||||
let mut blockchain = BlockChain::new(1);
|
||||
let block_data_channel_sender = channel(1).0;
|
||||
BlockChain::add_block(
|
||||
&mut blockchain,
|
||||
"Ahmet Kaan Gümüş".to_string(),
|
||||
instant,
|
||||
block_data_channel_sender.clone(),
|
||||
);
|
||||
assert_eq!(blockchain.chain[0].data, "Tahinli");
|
||||
assert_eq!(blockchain.chain[0].hash, "");
|
||||
assert_eq!(blockchain.chain[0].index, 0);
|
||||
assert_eq!(blockchain.chain[0].previous_hash, "");
|
||||
assert_eq!(blockchain.chain[0].proof_of_work, 0);
|
||||
assert_eq!(blockchain.chain[0].hash_time_cost, Duration::from_secs(0));
|
||||
assert_eq!(blockchain.chain[1].data, "Ahmet Kaan Gümüş");
|
||||
assert_eq!(blockchain.chain[1].previous_hash, "");
|
||||
assert_eq!(blockchain.chain[1].index, 1);
|
||||
assert_eq!(blockchain.chain.len(), 2);
|
||||
}
|
57
src/utils.rs
Normal file
57
src/utils.rs
Normal file
|
@ -0,0 +1,57 @@
|
|||
use std::{env, fs::File, io::Read};
|
||||
|
||||
use crate::{Runner, ServerConfig};
|
||||
|
||||
pub fn take_args() -> Option<Runner> {
|
||||
let args: Vec<String> = env::args().collect();
|
||||
if args.len() > 1 {
|
||||
match &args[1][..] {
|
||||
"--server" => Some(Runner::Server),
|
||||
"--client" => Some(Runner::Client),
|
||||
_ => None,
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_server_config() -> Option<ServerConfig> {
|
||||
let mut server_config_file = match File::open("configs/server_config.txt") {
|
||||
Ok(server_config_file) => server_config_file,
|
||||
Err(_) => return None,
|
||||
};
|
||||
let mut server_configs = String::new();
|
||||
match server_config_file.read_to_string(&mut server_configs) {
|
||||
Ok(_) => {
|
||||
let server_configs: Vec<String> =
|
||||
server_configs.split("\n").map(|x| x.to_string()).collect();
|
||||
let server_address = match server_configs[0].split(":").last() {
|
||||
Some(server_address_unchecked) => match server_address_unchecked.parse() {
|
||||
Ok(server_address) => server_address,
|
||||
Err(_) => return None,
|
||||
},
|
||||
None => return None,
|
||||
};
|
||||
let port = match server_configs[1].split(":").last() {
|
||||
Some(port_unchecked) => match port_unchecked.parse() {
|
||||
Ok(port) => port,
|
||||
Err(_) => return None,
|
||||
},
|
||||
None => return None,
|
||||
};
|
||||
let difficulty = match server_configs[2].split(":").last() {
|
||||
Some(difficulty_unchecked) => match difficulty_unchecked.parse() {
|
||||
Ok(difficulty) => difficulty,
|
||||
Err(_) => return None,
|
||||
},
|
||||
None => return None,
|
||||
};
|
||||
Some(ServerConfig {
|
||||
server_address,
|
||||
port,
|
||||
difficulty,
|
||||
})
|
||||
}
|
||||
Err(_) => None,
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue