bless
This commit is contained in:
parent
ffeb300e9e
commit
1ab99e475b
195
node/Cargo.lock
generated
195
node/Cargo.lock
generated
@ -331,6 +331,7 @@ dependencies = [
|
||||
"sled",
|
||||
"textwrap",
|
||||
"thiserror 2.0.16",
|
||||
"tinyhttp",
|
||||
"tokio",
|
||||
"tokio-tungstenite",
|
||||
"uuid",
|
||||
@ -396,6 +397,17 @@ dependencies = [
|
||||
"shlex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfb"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d38f2da7a0a2c4ccf0065be06397cc26a81f4e528be095826eee9d4adbb8c60f"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"fnv",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
@ -598,6 +610,15 @@ dependencies = [
|
||||
"cfg-if 1.0.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.18"
|
||||
@ -818,6 +839,12 @@ dependencies = [
|
||||
"litrs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dyn-clone"
|
||||
version = "1.0.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555"
|
||||
|
||||
[[package]]
|
||||
name = "ecdsa"
|
||||
version = "0.16.9"
|
||||
@ -910,6 +937,16 @@ dependencies = [
|
||||
"toml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fluent"
|
||||
version = "0.16.1"
|
||||
@ -966,6 +1003,21 @@ version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
|
||||
dependencies = [
|
||||
"foreign-types-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types-shared"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.2.2"
|
||||
@ -1463,6 +1515,15 @@ version = "2.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd"
|
||||
|
||||
[[package]]
|
||||
name = "infer"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb33622da908807a06f9513c19b3c1ad50fab3e4137d82a78107d502075aa199"
|
||||
dependencies = [
|
||||
"cfb",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inout"
|
||||
version = "0.1.4"
|
||||
@ -1697,6 +1758,22 @@ dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mime"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
||||
|
||||
[[package]]
|
||||
name = "mime_guess"
|
||||
version = "2.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e"
|
||||
dependencies = [
|
||||
"mime",
|
||||
"unicase",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
version = "0.2.1"
|
||||
@ -1797,6 +1874,16 @@ dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.36.7"
|
||||
@ -1830,6 +1917,44 @@ version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8"
|
||||
dependencies = [
|
||||
"bitflags 2.9.3",
|
||||
"cfg-if 1.0.3",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"openssl-macros",
|
||||
"openssl-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-macros"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.11.2"
|
||||
@ -1956,6 +2081,12 @@ dependencies = [
|
||||
"spki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
|
||||
|
||||
[[package]]
|
||||
name = "poly1305"
|
||||
version = "0.8.0"
|
||||
@ -2308,6 +2439,19 @@ version = "1.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
|
||||
|
||||
[[package]]
|
||||
name = "rusty_pool"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ed36cdb20de66d89a17ea04b8883fc7a386f2cf877aaedca5005583ce4876ff"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"futures",
|
||||
"futures-channel",
|
||||
"futures-executor",
|
||||
"num_cpus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.20"
|
||||
@ -2724,6 +2868,45 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyhttp"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40da872cd88188b99336266db850a3a87037dc463b376db7a422236427e3a0b6"
|
||||
dependencies = [
|
||||
"tinyhttp-codegen",
|
||||
"tinyhttp-internal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyhttp-codegen"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "020ea8639b093aa2a1f70cdcb07af1935ec1fcdcc36b3f7e1208751dbbf2470d"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn",
|
||||
"tinyhttp-internal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyhttp-internal"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58a51a6d7166b0083f7f9537a54cb749ce16ef73811bfd77452e4d4eab1c4389"
|
||||
dependencies = [
|
||||
"dyn-clone",
|
||||
"flate2",
|
||||
"infer",
|
||||
"log",
|
||||
"mime_guess",
|
||||
"num_cpus",
|
||||
"openssl",
|
||||
"rusty_pool",
|
||||
"thiserror 1.0.69",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinystr"
|
||||
version = "0.8.1"
|
||||
@ -2835,6 +3018,12 @@ dependencies = [
|
||||
"tinystr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicase"
|
||||
version = "2.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.18"
|
||||
@ -2940,6 +3129,12 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.5"
|
||||
|
||||
@ -32,3 +32,4 @@ ring = "0.17.14"
|
||||
shared = { path = "../shared", features = ["node"] }
|
||||
wallet = { path = "../wallet" }
|
||||
cli-renderer = { path = "../cli-renderer" }
|
||||
tinyhttp = { version = "0.5.0", features = ["async"] }
|
||||
|
||||
@ -0,0 +1,22 @@
|
||||
use std::net::TcpStream;
|
||||
|
||||
use tinyhttp;
|
||||
use tokio::net::{TcpListener, TcpSocket};
|
||||
|
||||
#[derive(Error, Clone)]
|
||||
enum HttpServerError {
|
||||
#[error("Socket Error: {0}")]
|
||||
SockerError(#[from] std::io::Error)
|
||||
}
|
||||
|
||||
async fn start_server() {
|
||||
let tcp_listner = TcpListener::bind("127.0.0.1:6080").await.unwrap();
|
||||
|
||||
let config = tinyhttp::prelude::Config::new();
|
||||
|
||||
let home_route = tinyhttp::prelude::Routes::new();
|
||||
|
||||
let server = tinyhttp::prelude::HttpListener::new(tcp_listner, config);
|
||||
|
||||
server.start();
|
||||
}
|
||||
@ -167,4 +167,10 @@ pub struct CliArgs {
|
||||
/// Enable debug mode (alternative syntax)
|
||||
#[arg(short = 's', long = "seed", action = clap::ArgAction::SetTrue)]
|
||||
pub seed: bool,
|
||||
|
||||
/// Run with temporary db
|
||||
#[arg(short = 't', long = "seed", action = clap::ArgAction::SetTrue)]
|
||||
pub temporary: bool,
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
use crate::args::*;
|
||||
use shared::core::ChainData;
|
||||
use vlogger::*;
|
||||
use crate::executor::ExecutorCommand;
|
||||
use crate::node::*;
|
||||
use crate::log;
|
||||
use cli_renderer::RenderCommand;
|
||||
use clap::Parser;
|
||||
|
||||
@ -53,7 +55,17 @@ pub fn cli(input: &str) -> ExecutorCommand {
|
||||
CliCommand::Transaction(tx) => {
|
||||
ExecutorCommand::Node(NodeCommand::ProcessChainData(ChainData::Transaction(tx)))
|
||||
}
|
||||
CliCommand::Award { address, amount } => {ExecutorCommand::Node(NodeCommand::AwardCurrency{ address, amount })}
|
||||
CliCommand::Award { address, amount } => {
|
||||
let mut bytes = [0u8; 20];
|
||||
if address.len() != 20 {
|
||||
log(msg!(ERROR, "Invalid address length"))
|
||||
} else if !address.is_ascii() {
|
||||
log(msg!(ERROR, "Invalid address content"))
|
||||
}
|
||||
|
||||
bytes.copy_from_slice(address.as_bytes());
|
||||
ExecutorCommand::Node(NodeCommand::AwardCurrency{ address: bytes, amount }
|
||||
)}
|
||||
CliCommand::DebugShowId => ExecutorCommand::Node(NodeCommand::ShowId),
|
||||
CliCommand::StartListner { addr } => {
|
||||
ExecutorCommand::Node(NodeCommand::StartListner(addr.parse().unwrap()))
|
||||
|
||||
@ -43,7 +43,7 @@ fn prefix(prefix: &[u8], key: &[u8]) -> Vec<u8> {
|
||||
}
|
||||
|
||||
impl ChainDb {
|
||||
pub fn new(path: Option<String>) -> Result<ChainDb, DatabaseError> {
|
||||
pub fn new(path: Option<String>, db_temp: bool) -> Result<ChainDb, DatabaseError> {
|
||||
let path = if path.is_some() {
|
||||
&path.unwrap()
|
||||
} else {
|
||||
@ -52,6 +52,7 @@ impl ChainDb {
|
||||
let config = sled::Config::new()
|
||||
.cache_capacity(512 * 1024)
|
||||
.segment_size(1024 * 1024)
|
||||
.temporary(db_temp)
|
||||
.path(&path);
|
||||
|
||||
match config.open() {
|
||||
@ -176,7 +177,7 @@ impl ChainDb {
|
||||
let mut chain_data = Vec::new();
|
||||
|
||||
for data_hash in &block.data {
|
||||
let data_hash = prefix(&CHAIN_DATA_PREFIX, data_hash.as_bytes());
|
||||
let data_hash = prefix(&CHAIN_DATA_PREFIX, data_hash);
|
||||
if let Some(bin_data) = self.db.get(&data_hash)? {
|
||||
let (data, _) = bincode::decode_from_slice::<ChainData, _>(&bin_data, BINCODE_CONFIG)?;
|
||||
chain_data.push(data);
|
||||
@ -211,14 +212,14 @@ impl ChainDb {
|
||||
pub fn add_block(&self, block: &core::Block) -> Result<(), DatabaseError> {
|
||||
let mut db_batch = Batch::default();
|
||||
let bin_block = bincode::encode_to_vec(block, BINCODE_CONFIG)?;
|
||||
db_batch.insert(prefix(&BLOCK_PREFIX, block.head().block_hash().as_bytes()), bin_block);
|
||||
db_batch.insert(prefix(&BLOCK_PREFIX, block.head().block_hash()), bin_block);
|
||||
db_batch.insert(
|
||||
prefix(&HEIGHT_TO_HASH_PREFIX, &block.head().height.to_be_bytes()),
|
||||
block.head().block_hash(),
|
||||
);
|
||||
for data in block.data() {
|
||||
db_batch.insert(
|
||||
prefix(&DATA_TO_BLOCK_PREFIX, data.as_bytes()),
|
||||
prefix(&DATA_TO_BLOCK_PREFIX, data),
|
||||
block.head().block_hash(),
|
||||
);
|
||||
}
|
||||
|
||||
@ -11,6 +11,11 @@ pub mod node {
|
||||
|
||||
pub mod cli;
|
||||
|
||||
pub mod api {
|
||||
pub mod server;
|
||||
pub use server::*;
|
||||
}
|
||||
|
||||
pub mod args;
|
||||
|
||||
pub mod error;
|
||||
|
||||
@ -18,6 +18,7 @@ async fn main() -> Result<(), std::io::Error> {
|
||||
.debug(args.debug)
|
||||
.render(args.render)
|
||||
.bootstrap(args.bootstrap)
|
||||
.temporary(args.temporary)
|
||||
.start()
|
||||
.await;
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
use std::sync::Arc;
|
||||
use std::time::UNIX_EPOCH;
|
||||
|
||||
use shared::core::Address;
|
||||
use thiserror::*;
|
||||
|
||||
use shared::core;
|
||||
@ -55,7 +56,7 @@ pub enum ValidationError {
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl Blockchain {
|
||||
fn hash_transaction_pool(&self) -> Vec<String> {
|
||||
fn hash_transaction_pool(&self) -> Vec<[u8; 32]> {
|
||||
self
|
||||
.mempool
|
||||
.iter()
|
||||
@ -63,17 +64,23 @@ impl Blockchain {
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn award_currency(&self, address: String, amount: u64) -> Result<(), BlockchainError> {
|
||||
Ok(self.db.add_balance(&address, amount)?)
|
||||
pub fn award_currency(&self, address: Address, amount: u64) -> Result<(), BlockchainError> {
|
||||
let previous_balance = self.db.get_balance(&address)?;
|
||||
let new_balance = if previous_balance.is_some() {
|
||||
previous_balance.unwrap() + amount
|
||||
} else {
|
||||
amount
|
||||
};
|
||||
Ok(self.db.set_balance(&address, new_balance)?)
|
||||
}
|
||||
|
||||
pub fn create_block(&mut self) -> Result<Arc<core::Block>, BlockchainError> {
|
||||
match self.blocks() {
|
||||
Ok(blocks) => {
|
||||
let previous_hash = if blocks.len() > 0 {
|
||||
blocks.last().unwrap().head().block_hash()
|
||||
<[u8; 32]>::try_from(blocks.last().unwrap().head().block_hash()).unwrap()
|
||||
} else {
|
||||
""
|
||||
[0u8; 32]
|
||||
};
|
||||
let tx_hashes = self.hash_transaction_pool();
|
||||
let merkle_root = Hasher::calculate_merkle_root(&tx_hashes);
|
||||
@ -85,16 +92,16 @@ impl Blockchain {
|
||||
let nonce = 0;
|
||||
|
||||
let mut new_head = core::BlockHeader {
|
||||
previous_hash: previous_hash.to_string(),
|
||||
previous_hash: <[u8; 32]>::from(previous_hash),
|
||||
merkle_root,
|
||||
timestamp,
|
||||
nonce,
|
||||
height: blocks.len() as u64 + 1,
|
||||
block_hash: "".to_string(),
|
||||
block_hash: [0u8; 32],
|
||||
};
|
||||
|
||||
let mut block_hash = String::new();
|
||||
while !block_hash.starts_with("0") {
|
||||
let mut block_hash = [0u8; 32];
|
||||
while !block_hash.starts_with(b"0") {
|
||||
new_head.nonce += 1;
|
||||
block_hash = Hasher::calculate_block_hash(&new_head)
|
||||
}
|
||||
@ -121,7 +128,7 @@ impl Blockchain {
|
||||
};
|
||||
|
||||
if tx.value() > from_balance {
|
||||
return Err(BlockchainError::InsufficientFunds(tx.from().to_string()))
|
||||
return Err(BlockchainError::InsufficientFunds(hex::encode(from)))
|
||||
}
|
||||
|
||||
let new_from_balance = from_balance - tx.value();
|
||||
@ -130,7 +137,7 @@ impl Blockchain {
|
||||
let changes = vec![(from, new_from_balance), (to, new_to_balance)];
|
||||
Ok(self.db.set_balance_batch(changes)?)
|
||||
} else {
|
||||
Err(BlockchainError::Database(DatabaseError::AccountNotFound(from.to_string())))
|
||||
Err(BlockchainError::Database(DatabaseError::AccountNotFound(hex::encode(from))))
|
||||
}
|
||||
}
|
||||
|
||||
@ -146,11 +153,11 @@ impl Blockchain {
|
||||
}
|
||||
|
||||
impl Blockchain {
|
||||
pub fn list_blocks(&self) -> Result<Vec<String>, BlockchainError> {
|
||||
pub fn list_blocks(&self) -> Result<Vec<[u8; 32]>, BlockchainError> {
|
||||
let mut ret = Vec::new();
|
||||
let blocks = self.blocks()?;
|
||||
for b in blocks.iter() {
|
||||
ret.push(b.head.block_hash().to_string())
|
||||
ret.push(<[u8; 32]>::try_from(b.head.block_hash()).unwrap())
|
||||
}
|
||||
Ok(ret)
|
||||
}
|
||||
@ -224,8 +231,8 @@ impl Blockchain {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn build(path: Option<String>) -> Result<Blockchain, BlockchainError> {
|
||||
let db = db::ChainDb::new(path).or_else(|e| Err(BlockchainError::Database(e)))?;
|
||||
pub fn build(path: Option<String>, db_temp: bool) -> Result<Blockchain, BlockchainError> {
|
||||
let db = db::ChainDb::new(path, db_temp).or_else(|e| Err(BlockchainError::Database(e)))?;
|
||||
let mempool = db.recover_mempool()?;
|
||||
|
||||
let chain = Blockchain {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use crate::bus::{publish_system_event, publish_watcher_event, subscribe_system_event, SystemEvent};
|
||||
use shared::core::{self, ChainData};
|
||||
use shared::core::print_error_chain;
|
||||
use shared::print_error_chain;
|
||||
use crate::executor::ExecutorCommand;
|
||||
use crate::log;
|
||||
use crate::protocol::ProtocolMessage;
|
||||
@ -76,7 +76,7 @@ pub enum NodeCommand {
|
||||
ListBlocks,
|
||||
ListPeers,
|
||||
ShowId,
|
||||
AwardCurrency { address: String, amount: u64 },
|
||||
AwardCurrency { address: [u8; 20], amount: u64 },
|
||||
ConnectToSeeds,
|
||||
ConnectTcpPeer(String),
|
||||
BootStrap,
|
||||
@ -203,7 +203,7 @@ impl Node {
|
||||
}
|
||||
ProtocolMessage::BootstrapResponse { blocks } => {
|
||||
log(msg!(DEBUG, "Received BootstrapResponse from seed"));
|
||||
self.chain = Blockchain::build(blocks).unwrap();
|
||||
self.chain = Blockchain::build(blocks, true).unwrap();
|
||||
}
|
||||
ProtocolMessage::Pong { peer_id } => {
|
||||
log(msg!(DEBUG, "Received Pong from {peer_id}"));
|
||||
@ -397,6 +397,7 @@ impl Node {
|
||||
NodeCommand::RemovePeer { peer_id } => {
|
||||
self.remove_tcp_peer(peer_id).await;
|
||||
}
|
||||
|
||||
NodeCommand::ProcessMessage { peer_id, message } => {
|
||||
self.process_message(peer_id, message).await;
|
||||
}
|
||||
@ -417,7 +418,7 @@ impl Node {
|
||||
log(msg!(
|
||||
INFO,
|
||||
"Created Block with hash {}",
|
||||
block.head().block_hash()
|
||||
hex::encode(block.head().block_hash())
|
||||
));
|
||||
self.broadcast_block(&block).await;
|
||||
}
|
||||
@ -428,7 +429,7 @@ impl Node {
|
||||
Err(e) => return print_error_chain(&e.into()),
|
||||
};
|
||||
let wat_cmd = WatcherCommand::SetMode(WatcherMode::Select {
|
||||
content: blocks.into(),
|
||||
content: blocks.iter().map(|h| hex::encode(h)).collect::<Vec<String>>().into(),
|
||||
title: "Select Block to display".to_string(),
|
||||
callback: Box::new(ExecutorCommand::Node(NodeCommand::DisplayBlockByKey("".to_string()))),
|
||||
index: 0
|
||||
@ -440,7 +441,7 @@ impl Node {
|
||||
NodeCommand::ListBlocks => {
|
||||
log(msg!(DEBUG, "Received DebugListBlocks command"));
|
||||
match self.chain.list_blocks() {
|
||||
Ok(s) => log(s.join("\n")),
|
||||
Ok(s) => log(s.iter().map(|h| format!("{}\n", hex::encode(h))).collect::<Vec<String>>().join("\n")),
|
||||
Err(e) => print_error_chain(&e.into()),
|
||||
}
|
||||
}
|
||||
@ -471,6 +472,7 @@ impl Node {
|
||||
))
|
||||
.await;
|
||||
};
|
||||
|
||||
let mut system_rx = subscribe_system_event();
|
||||
publish_system_event(SystemEvent::NodeStarted);
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@ use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||
use tokio::net;
|
||||
use tokio::sync::mpsc;
|
||||
use vlogger::*;
|
||||
use shared::core::print_error_chain;
|
||||
use shared::print_error_chain;
|
||||
use thiserror::*;
|
||||
|
||||
use crate::log;
|
||||
|
||||
@ -18,6 +18,7 @@ pub struct WatcherBuilder {
|
||||
debug: bool,
|
||||
seed: bool,
|
||||
render: bool,
|
||||
temporary: bool
|
||||
}
|
||||
|
||||
impl WatcherBuilder {
|
||||
@ -55,6 +56,11 @@ impl WatcherBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn temporary(mut self, temporary: bool) -> Self {
|
||||
self.temporary = temporary;
|
||||
self
|
||||
}
|
||||
|
||||
pub async fn start(mut self) -> Watcher {
|
||||
let (exec_tx, exec_rx) = mpsc::channel::<ExecutorCommand>(100);
|
||||
let mut sys_event = subscribe_system_event();
|
||||
@ -70,7 +76,7 @@ impl WatcherBuilder {
|
||||
self.addr = Some(crate::seeds_constants::SEED_NODES[0]);
|
||||
}
|
||||
|
||||
let chain = node::Blockchain::build(None).unwrap();
|
||||
let chain = node::Blockchain::build(None, self.temporary).unwrap();
|
||||
let mut node = Node::new(self.addr.clone(), exec_tx.clone(), chain);
|
||||
log(msg!(INFO, "Built Node"));
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ use crate::{
|
||||
watcher::WatcherMode
|
||||
};
|
||||
|
||||
use shared::core::print_error_chain;
|
||||
use shared::print_error_chain;
|
||||
use crossterm::event::{Event, EventStream, KeyCode, KeyEventKind, MouseButton, MouseEventKind};
|
||||
use futures::StreamExt;
|
||||
use memory_stats::memory_stats;
|
||||
|
||||
12
node_client/app.js
Normal file
12
node_client/app.js
Normal file
@ -0,0 +1,12 @@
|
||||
const connection = {
|
||||
ws: [],
|
||||
node_list: [],
|
||||
}
|
||||
|
||||
function establishConnection() {
|
||||
const ws = new WebSocket('ws://localhost:6000');
|
||||
}
|
||||
|
||||
function updateTableStats() {
|
||||
|
||||
}
|
||||
76
node_client/index.html
Normal file
76
node_client/index.html
Normal file
@ -0,0 +1,76 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title></title>
|
||||
<!-- <link href="css/style.css" rel="stylesheet"> -->
|
||||
</head>
|
||||
<body class="background">
|
||||
<div class="main-container">
|
||||
<h1>Node Stats</h1>
|
||||
<div class="table-container">
|
||||
<table style="box-sizing: border-box; max-height: 100%; width: 100%; table-layout: fixed; border-collapse: collapse;" id='stat-table' >
|
||||
<thead>
|
||||
<tr style="border-bottom: 1px solid black;">
|
||||
<th>stat 1</th>
|
||||
<th>stat 2</th>
|
||||
<th>stat 3</th>
|
||||
<th>stat 4</th>
|
||||
<th>stat 5</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody style="box-sizing: border-box; max-height: 100%; overflow-y: scroll;"id='stat-table-body'>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/app.js" ></script>
|
||||
<script>
|
||||
const table = document.getElementById('stat-table-body');
|
||||
for (var i = 0; i < 30; i++)
|
||||
{
|
||||
const new_row = document.createElement('tr');
|
||||
let row_content = '';
|
||||
for (var j = 0; j < 5; j++) {
|
||||
row_content += `<td style="text-align: right; padding: 0 4px ; border-top: 1px solid black;">${i + j}</td>`
|
||||
}
|
||||
new_row.innerHTML = row_content;
|
||||
table.appendChild(new_row);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.main-container {
|
||||
padding: 6px;
|
||||
display: flex;
|
||||
align-content: center;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.table-container {
|
||||
padding: 6px;
|
||||
place-self: center;
|
||||
border: 2px solid #000000;
|
||||
width: 50%;
|
||||
height: 50%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.background {
|
||||
background-color: #808080;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
max-height: 100vh;
|
||||
max-width: 100vw;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
||||
</html>
|
||||
@ -2,10 +2,10 @@
|
||||
Clone, Debug, serde::Deserialize, serde::Serialize, Default, bincode::Decode, bincode::Encode,
|
||||
)]
|
||||
pub struct BlockHeader {
|
||||
pub previous_hash: String,
|
||||
pub previous_hash: [u8; 32],
|
||||
pub timestamp: u64,
|
||||
pub merkle_root: String,
|
||||
pub block_hash: String,
|
||||
pub merkle_root: [u8; 32],
|
||||
pub block_hash: [u8; 32],
|
||||
pub nonce: u32,
|
||||
pub height: u64,
|
||||
}
|
||||
@ -15,11 +15,11 @@ pub struct BlockHeader {
|
||||
)]
|
||||
pub struct Block {
|
||||
pub head: BlockHeader,
|
||||
pub data: Vec<String>,
|
||||
pub data: Vec<[u8; 32]>,
|
||||
}
|
||||
|
||||
impl BlockHeader {
|
||||
pub fn previous_hash(&self) -> &str {
|
||||
pub fn previous_hash(&self) -> &[u8] {
|
||||
&self.previous_hash
|
||||
}
|
||||
pub fn timestamp(&self) -> u64 {
|
||||
@ -28,22 +28,22 @@ impl BlockHeader {
|
||||
pub fn nonce(&self) -> u32 {
|
||||
self.nonce
|
||||
}
|
||||
pub fn merkle_root(&self) -> &str {
|
||||
pub fn merkle_root(&self) -> &[u8] {
|
||||
&self.merkle_root
|
||||
}
|
||||
pub fn block_hash(&self) -> &str {
|
||||
pub fn block_hash(&self) -> &[u8] {
|
||||
&self.block_hash
|
||||
}
|
||||
}
|
||||
|
||||
impl Block {
|
||||
pub fn new(head: BlockHeader, data: Vec<String>) -> Self {
|
||||
pub fn new(head: BlockHeader, data: Vec<[u8; 32]>) -> Self {
|
||||
Self { head, data }
|
||||
}
|
||||
pub fn head(&self) -> &BlockHeader {
|
||||
&self.head
|
||||
}
|
||||
pub fn data(&self) -> &[String] {
|
||||
pub fn data(&self) -> &[[u8; 32]] {
|
||||
&self.data
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,7 +21,7 @@ impl Hasher {
|
||||
res.into()
|
||||
}
|
||||
|
||||
pub fn calculate_next_level(level: &[String]) -> Vec<String> {
|
||||
pub fn calculate_next_level(level: &[[u8; 32]]) -> Vec<[u8; 32]> {
|
||||
let mut next_level = Vec::new();
|
||||
|
||||
for chunk in level.chunks(2) {
|
||||
@ -35,9 +35,9 @@ impl Hasher {
|
||||
next_level
|
||||
}
|
||||
|
||||
pub fn calculate_merkle_root(tx_hashes: &[String]) -> String {
|
||||
pub fn calculate_merkle_root(tx_hashes: &[[u8; 32]]) -> [u8; 32] {
|
||||
if tx_hashes.is_empty() {
|
||||
return Self::hash_data("");
|
||||
return Self::hash_data(b"");
|
||||
}
|
||||
|
||||
if tx_hashes.len() == 1 {
|
||||
@ -53,18 +53,20 @@ impl Hasher {
|
||||
return current_level[0].clone();
|
||||
}
|
||||
|
||||
fn hash_pair(left: &str, right: &str) -> String {
|
||||
let combined = format!("{}{}", left, right);
|
||||
fn hash_pair(left: &[u8], right: &[u8]) -> [u8; 32] {
|
||||
let mut combined = Vec::with_capacity(left.len() + right.len());
|
||||
combined.copy_from_slice(left);
|
||||
combined.copy_from_slice(right);
|
||||
Self::hash_data(&combined)
|
||||
}
|
||||
|
||||
fn hash_data(data: &str) -> String {
|
||||
fn hash_data(data: &[u8]) -> [u8; 32] {
|
||||
let mut hasher = Sha256::new();
|
||||
hasher.update(data.as_bytes());
|
||||
hex::encode(hasher.finalize())
|
||||
hasher.update(data);
|
||||
hasher.finalize().into()
|
||||
}
|
||||
|
||||
pub fn calculate_block_hash(head: &BlockHeader) -> String {
|
||||
pub fn calculate_block_hash(head: &BlockHeader) -> [u8; 32] {
|
||||
let mut hasher = sha2::Sha256::new();
|
||||
|
||||
hasher.update(head.nonce().to_be_bytes());
|
||||
@ -73,6 +75,6 @@ impl Hasher {
|
||||
hasher.update(head.merkle_root());
|
||||
|
||||
let res = hasher.finalize();
|
||||
hex::encode(res)
|
||||
res.into()
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user