-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e72da97
commit 6aafcc5
Showing
10 changed files
with
264 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
btc_mine_simulator/target/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
target |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
[package] | ||
name = "btc_mine_simulator" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
serde = { version = "1.0", features = ["derive"] } | ||
serde_json = "1.0" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
use std::fs; | ||
use std::io; | ||
use std::path::Path; | ||
|
||
mod tx; | ||
mod validate; | ||
use tx::Transaction; | ||
use validate::validate_transaction; | ||
|
||
fn read_transactions_from_dir(dir: &Path) -> io::Result<(Vec<Transaction>, usize, usize)> { | ||
let mut transactions = Vec::new(); | ||
let mut total_files = 0; | ||
let mut failed_parses = 0; | ||
|
||
for entry in fs::read_dir(dir)? { | ||
let entry = entry?; | ||
let path = entry.path(); | ||
if path.is_file() { | ||
total_files += 1; | ||
match fs::read_to_string(&path) { | ||
Ok(data) => { | ||
match serde_json::from_str::<Transaction>(&data) { | ||
Ok(transaction) => transactions.push(transaction), | ||
Err(e) => { // Capture the parse error | ||
failed_parses += 1; | ||
println!("Failed to parse file: {:?}, Reason: {}", path.display(), e); | ||
// Prints out the specific reason for the parse failure | ||
}, | ||
} | ||
}, | ||
Err(e) => { // Capture the file read error | ||
println!("Failed to read file: {:?}, Reason: {}", path.display(), e); | ||
// This case handles file read errors | ||
} | ||
} | ||
} | ||
} | ||
for tx in &transactions { | ||
// println!("{:?}", tx.locktime); | ||
if tx.locktime != 0 { | ||
println!("wow {:?}", tx.locktime); | ||
} | ||
} | ||
|
||
println!("Total files processed: {}", total_files); | ||
println!("Failed to parse: {}", failed_parses); | ||
Ok((transactions, total_files, failed_parses)) | ||
} | ||
|
||
fn main() { | ||
let dir = Path::new("../mempool"); | ||
let txs = match read_transactions_from_dir(dir) { | ||
Ok((transactions, total_files, failed_parses)) => { | ||
println!("Successfully parsed transactions: {}", transactions.len()); | ||
println!("Total files: {}", total_files); | ||
println!("Failed parses: {}", failed_parses); | ||
transactions | ||
}, | ||
Err(e) => panic!("Error reading transactions: {}", e), | ||
}; | ||
let mut res = 0; | ||
for tx in &txs { | ||
if let Err(e) = validate_transaction(tx) { | ||
println!("{:?}", tx.); | ||
res += 1; | ||
println!("error: {:?}", e); | ||
|
||
} | ||
|
||
} | ||
println!("{:?}", res); | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
use serde::{Deserialize, Serialize}; | ||
|
||
#[derive(Serialize, Deserialize, Debug)] | ||
pub struct Transaction { | ||
pub version: i32, | ||
pub locktime: u32, | ||
pub vin: Vec<Input>, | ||
pub vout: Vec<Output>, | ||
} | ||
|
||
#[derive(Serialize, Deserialize, Debug)] | ||
pub struct Input { | ||
pub txid: String, | ||
pub vout: u32, | ||
pub prevout: PrevOut, | ||
pub scriptsig: String, | ||
pub scriptsig_asm: String, | ||
pub witness: Option<Vec<String>>, | ||
pub is_coinbase: bool, | ||
pub sequence: u32, | ||
} | ||
|
||
#[derive(Serialize, Deserialize, Debug)] | ||
pub struct PrevOut { | ||
pub scriptpubkey: String, | ||
pub scriptpubkey_asm: String, | ||
pub scriptpubkey_type: String, | ||
pub scriptpubkey_address: String, | ||
pub value: u64, | ||
} | ||
|
||
#[derive(Serialize, Deserialize, Debug)] | ||
pub struct Output { | ||
pub scriptpubkey: String, | ||
pub scriptpubkey_asm: String, | ||
pub scriptpubkey_type: String, | ||
pub scriptpubkey_address: Option<String>, | ||
pub value: u64, | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
use serde::{Deserialize, Serialize}; | ||
|
||
use crate::tx::Transaction; | ||
|
||
// Assuming the structs Transaction, Input, Output, PrevOut are defined as above | ||
|
||
pub fn validate_transaction(tx: &Transaction) -> Result<(), String> { | ||
if tx.version < 1 || tx.version > 2 { | ||
return Err("Unsupported transaction version".to_string()); | ||
} | ||
|
||
if tx.vin.is_empty() { | ||
return Err("Transaction has no inputs".to_string()); | ||
} | ||
|
||
if tx.vout.is_empty() { | ||
return Err("Transaction has no outputs".to_string()); | ||
} | ||
|
||
for input in &tx.vin { | ||
if input.is_coinbase && tx.vin.len() > 1 { | ||
return Err("Coinbase transaction has more than one input".to_string()); | ||
} | ||
|
||
if !input.is_coinbase && input.txid.is_empty() { | ||
return Err("Input txid is empty".to_string()); | ||
} | ||
|
||
if let Some(witness) = &input.witness { | ||
if witness.is_empty() { | ||
return Err("Witness is present but empty".to_string()); | ||
} | ||
} | ||
} | ||
|
||
// let total_output_value: u64 = tx.vout.iter().map(|output| output.value).sum(); | ||
// if total_output_value == 0 { | ||
// return Err("Total output value is 0".to_string()); | ||
// } | ||
|
||
// Further checks can include scriptsig and scriptpubkey validation, which are complex and require executing the scripts | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
1. clean up invalid tx | ||
2. compute size and fee for each tx | ||
3. build dep graph, tx1 <- tx2 if tx2 can only be valid after tx1 executed | ||
4. try out some algo, simple one would be greedy with pq, consistently choose the max fee tx that can be selected, but this would def miss some some large fee tx with long dep of tx before it | ||
5. build block with selected tx, find the hash | ||
6. export result to file |