Skip to content

Commit

Permalink
Adding some validations for tx, implementation of block.push_transact…
Browse files Browse the repository at this point in the history
…ion() and modularization of lib.rs
  • Loading branch information
gabrielgusn committed Apr 25, 2024
1 parent f2a7a6b commit f7eedf6
Show file tree
Hide file tree
Showing 7 changed files with 200 additions and 77 deletions.
2 changes: 1 addition & 1 deletion mempool/0.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"scriptpubkey_asm": "123",
"scriptpubkey_type": "123",
"scriptpubkey_address": "123",
"value": 37079526
"value": 534
},
"scriptsig": "",
"scriptsig_asm": "",
Expand Down
36 changes: 31 additions & 5 deletions src/block/block.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
#![allow(dead_code, unused)]

use super::block_header::BlockHeader;
use crate::transactions::tx::Tx;
use crate::transactions::{self, tx::Tx};
use core::fmt;

const BLOCK_MAX_SIZE: u32 = 8000000;

#[derive(Debug)]
pub struct Block{
pub block_header: BlockHeader,
Expand All @@ -16,12 +19,32 @@ impl Block {
Self{
block_header: block_header.clone(),
transactions,
block_size: block_header.get_block_header_size(),
block_size: block_header.get_block_header_size() + 32,
}
}

pub fn get_block_header_size(){
pub fn calculate_total_block_fee(&self) -> u64 {
let mut total_fee: u64 = 0;

for tx in &self.transactions{
total_fee += tx.get_tx_fee();
}

return total_fee;
}

pub fn get_block_size_left(&self) -> u32 {
BLOCK_MAX_SIZE - self.block_size
}

pub fn push_transaction(&mut self, tx: Tx) {
if self.block_size + tx.get_tx_size_in_bits() <= BLOCK_MAX_SIZE {
self.block_size += tx.get_tx_size_in_bits();
self.transactions.push(tx);
}
else {
println!("It is not possible to attach this tx to the block\n\tThe Tx Size is {} and the remaining space in the block is {}", tx.get_tx_size_in_bits(), self.block_size);
}
}

fn get_block_header_hash(&self) -> String {
Expand Down Expand Up @@ -54,12 +77,15 @@ impl fmt::Display for Block {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"Block ID: {}\nMerkle Root: {}\nTimestamp: {}\nNonce: {}\n\tTransactions: {:?}",
"Block ID: {}\nMerkle Root: {}\nTimestamp: {}\nNonce: {}\n\tAmount of Transactions: {:?}\n\tTotal Fee: {}\n\tBlock Size in KB: {} KBs\n\tBlock Size in Bits: {} Bits",
self.block_header.block_id,
self.block_header.txs_merkle_root,
self.block_header.timestamp,
self.block_header.nonce,
self.transactions,
self.transactions.len(),
self.calculate_total_block_fee(),
(self.get_block_size() / 8 / 1000),
self.get_block_size()
)
}
}
104 changes: 52 additions & 52 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,68 +1,68 @@
// use std::env;
#![allow(dead_code, unused)]
// // use std::env;
// #![allow(dead_code, unused)]

mod transactions;
mod mempool;
// use core::panicking::panic;
use std::io::{self, Read};
use std::fs::{self, File};
use std::path::Path;
use serde_json;
use transactions::tx::{Tx, TxInput, TxOutput};
use mempool::mempool::Mempool;
// mod transactions;
// mod mempool;
// // use core::panicking::panic;
// use std::io::{self, Read};
// use std::fs::{self, File};
// use std::path::Path;
// use serde_json;
// use transactions::tx::{Tx, TxInput, TxOutput};
// use mempool::mempool::Mempool;

pub fn read_mempool(path: &str){
// pub fn read_mempool(path: &str){

// let files = get_files_in_directory(path)
// .expect("Error while reading Dir");
// // let files = get_files_in_directory(path)
// // .expect("Error while reading Dir");

// let tx = read_tx_from_file("/home/gabriel/projects/bitcoin-mining-challenge/mempool/0.json");
// // let tx = read_tx_from_file("/home/gabriel/projects/bitcoin-mining-challenge/mempool/0.json");

let mut mempool: Mempool = Mempool::get_mempool_from_dir(path);
// let mut mempool: Mempool = Mempool::get_mempool_from_dir(path);

println!("{}", mempool.txs.len());
// println!("{}", mempool.txs.len());

println!("==================== Before sorting ====================");
for i in 0..100{
println!("{}", mempool.txs[i]);
}
// println!("==================== Before sorting ====================");
// for i in 0..100{
// println!("{}", mempool.txs[i]);
// }

println!("==================== After sorting ====================");
mempool.sort_mempool_by_tx();
for i in 0..100{
println!("{}", mempool.txs[i]);
}
}
// println!("==================== After sorting ====================");
// mempool.sort_mempool_by_tx();
// for i in 0..100{
// println!("{}", mempool.txs[i]);
// }
// }

pub fn read_tx_from_file(file_path: &str) -> Tx {
let mut file_content: String = String::new();
let path = Path::new(&file_path);
// pub fn read_tx_from_file(file_path: &str) -> Tx {
// let mut file_content: String = String::new();
// let path = Path::new(&file_path);

let mut file = File::open(path).expect("Error while loading file");
file.read_to_string(&mut file_content).expect("File can not be read");
// let mut file = File::open(path).expect("Error while loading file");
// file.read_to_string(&mut file_content).expect("File can not be read");

let error_in_file_message:String = String::from("Error while parsing json to Tx in file ") + file_path;
// let error_in_file_message:String = String::from("Error while parsing json to Tx in file ") + file_path;

let tx_in_json: Tx = serde_json::from_str(&file_content).expect(&error_in_file_message);
// let tx_in_json: Tx = serde_json::from_str(&file_content).expect(&error_in_file_message);

return tx_in_json;
}
// return tx_in_json;
// }

fn get_files_in_directory(path: &str) -> io::Result<Vec<String>> {
// Get a list of all entries in the folder
let entries = fs::read_dir(path)?;
// fn get_files_in_directory(path: &str) -> io::Result<Vec<String>> {
// // Get a list of all entries in the folder
// let entries = fs::read_dir(path)?;

// Extract the filenames from the directory entries and store them in a vector
let file_names: Vec<String> = entries
.filter_map(|entry| {
let path = entry.ok()?.path();
if path.is_file() {
path.file_name()?.to_str().map(|s| s.to_owned())
} else {
None
}
})
.collect();
// // Extract the filenames from the directory entries and store them in a vector
// let file_names: Vec<String> = entries
// .filter_map(|entry| {
// let path = entry.ok()?.path();
// if path.is_file() {
// path.file_name()?.to_str().map(|s| s.to_owned())
// } else {
// None
// }
// })
// .collect();

Ok(file_names)
}
// Ok(file_names)
// }
36 changes: 25 additions & 11 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,50 @@
#![allow(dead_code, unused)]
mod block;
mod transactions;
mod mempool;
mod utils;
use block::block_header::BlockHeader;
use block::block::Block;
use chrono::Utc;
use mining_challenge::{read_mempool, read_tx_from_file};
use utils::{read_mempool, read_tx_from_file};
use ring::digest::{Context, Digest, SHA256};
use std::fmt::Write;
// use hex_literal::hex;
use mempool::mempool::Mempool;
use std::fs;
// use transactions::tx;

fn main() {
// let file_size = fs::metadata("/home/gabriel/projects/bitcoin-mining-challenge/mempool/ff73248e38bfcdac87261f5a51f3143478937fda6b0d1def46e794b8f250e6dd.json").expect("Falha ao ler o arquivo");
// println!("Size: {} ", file_size.len());
read_mempool("/home/gabriel/projects/bitcoin-mining-challenge/mempool/");
let mut mempool: Mempool = read_mempool("/home/gabriel/projects/bitcoin-mining-challenge/mempool/");
mempool.sort_mempool_by_tx();

// let mut hasher = Sha256::new();
let first_block_header: BlockHeader = BlockHeader::new(String::from("00000000000000000000000000000000"), String::from("00000000000000000000000000000000"), Utc::now(), 128);
let block = Block::new(first_block_header, vec![]);

let mut block = Block::new(first_block_header, vec![]);

for tx in mempool.txs{
if tx.get_tx_size_in_bits() < block.get_block_size_left(){
block.push_transaction(tx);
}
else {
continue;
}
}

println!("{}", block);

// println!("=================================");
// println!("{}", first_block_header);
// println!("=================================");
// println!("1st Block Hash: {}", first_block_header.get_block_header_sha256sum());
// println!("Size of Block Header: {}", std::mem::size_of::<BlockHeader>());

let mut block_vec: Vec<Block> = vec![];
// let mut block_vec: Vec<Block> = vec![];

// block_vec.push(block);

// loop {

block_vec.push(block);
// }

// for i in 0..10{

Expand Down Expand Up @@ -76,5 +92,3 @@ fn main() {
// nonce += 1;
// }
}


17 changes: 10 additions & 7 deletions src/mempool/mempool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
use std::fmt::Formatter;
use core::fmt;
use crate::transactions::tx::Tx;
use crate::{get_files_in_directory, read_tx_from_file};
use crate::utils::{read_tx_from_file, get_files_in_directory};
// use crate::get_files_in_directory;

#[derive(Debug)]
pub struct Mempool {
Expand All @@ -20,16 +21,18 @@ impl Mempool{
}

pub fn get_mempool_from_dir(dir_path: &str) -> Mempool {
let files: Vec<String> = get_files_in_directory(dir_path).expect("Error while reading mempool directory");
let files: Vec<String> = get_files_in_directory(&dir_path).expect("Error while reading mempool directory");

let mut mempool: Mempool = Mempool::new();

for file in files{
let file_path = dir_path.to_string() + &file;

for file in files{

let file_path: String = dir_path.to_string() + &file;
let tx: Tx = read_tx_from_file(&file_path);

mempool.txs.push(tx);

if tx.pre_validate_tx() {
mempool.txs.push(tx);
}
}

return mempool;
Expand Down
14 changes: 13 additions & 1 deletion src/transactions/tx.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#![allow(dead_code, unused)]
// use ring::digest;


use core::{hash, fmt};
use sha2::{Digest, Sha256, Sha256VarCore};
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -110,8 +111,19 @@ impl Tx{
}

pub fn pre_validate_tx(&self) -> bool {
let mut tx_validity: bool = true;

if self.get_tx_input_value() < self.get_tx_output_value(){
tx_validity = false
}

for output in &self.tx_output{
if output.scriptpubkey_type == "unknown" {
tx_validity = false
}
}

true || false
return tx_validity;
}

}
Expand Down
68 changes: 68 additions & 0 deletions src/utils/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// use std::env;
#![allow(dead_code, unused)]

// use core::panicking::panic;

use crate::transactions::tx::{Tx, TxInput, TxOutput};
use crate::mempool::mempool::Mempool;
use serde_json;
use std::path::Path;
use std::io::{self, Read};
use std::fs::{self, File};

pub fn read_mempool(path: &str) -> Mempool {

// let files = get_files_in_directory(path)
// .expect("Error while reading Dir");

// let tx = read_tx_from_file("/home/gabriel/projects/bitcoin-mining-challenge/mempool/0.json");

let mut mempool: Mempool = Mempool::get_mempool_from_dir(path);

// println!("{:?}", mempool);

// println!("==================== Before sorting ====================");
// for i in 0..100{
// println!("{}", mempool.txs[i]);
// }

// println!("==================== After sorting ====================");
// mempool.sort_mempool_by_tx();
// for i in 0..100{
// println!("{}", mempool.txs[i]);
// }
mempool
}

pub fn get_files_in_directory(path: &str) -> io::Result<Vec<String>> {
// Get a list of all entries in the folder
let entries = fs::read_dir(path)?;

// Extract the filenames from the directory entries and store them in a vector
let file_names: Vec<String> = entries
.filter_map(|entry| {
let path = entry.ok()?.path();
if path.is_file() {
path.file_name()?.to_str().map(|s| s.to_owned())
} else {
None
}
})
.collect();

Ok(file_names)
}

pub fn read_tx_from_file(file_path: &str) -> Tx {
let mut file_content: String = String::new();
let path = Path::new(&file_path);

let mut file = File::open(path).expect("Error while loading file");
file.read_to_string(&mut file_content).expect("File can not be read");

let error_message_in_file:String = String::from("Error while parsing json to Tx in file ") + file_path;

let tx_in_json: Tx = serde_json::from_str(&file_content).expect(&error_message_in_file);

return tx_in_json;
}

0 comments on commit f7eedf6

Please sign in to comment.