Skip to content

Instantly share code, notes, and snippets.

@RandyMcMillan
Forked from rust-play/playground.rs
Last active June 10, 2026 17:52
Show Gist options
  • Select an option

  • Save RandyMcMillan/7c6a394a6d206a931ac5754e0413c245 to your computer and use it in GitHub Desktop.

Select an option

Save RandyMcMillan/7c6a394a6d206a931ac5754e0413c245 to your computer and use it in GitHub Desktop.
byz_fee_engine.rs
use chrono::{DateTime, Duration, Utc, Timelike};
use std::sync::{Arc, Mutex};
use std::time::Duration as StdDuration;
// --- CONSTANTS ---
const SHA256_K: [u32; 64] = [
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
];
// --- GIT-COMPLIANT SHA-1 ENGINE ---
fn git_sha1(data: &[u8]) -> String {
let mut h0: u32 = 0x67452301; let mut h1: u32 = 0xEFCDAB89;
let mut h2: u32 = 0x98BADCFE; let mut h3: u32 = 0x10325476;
let mut h4: u32 = 0xC3D2E1F0;
let mut padded = data.to_vec();
let bit_len = (padded.len() as u64) * 8;
padded.push(0x80);
while (padded.len() * 8) % 512 != 448 { padded.push(0); }
padded.extend_from_slice(&bit_len.to_be_bytes());
for chunk in padded.chunks(64) {
let mut w = [0u32; 80];
for i in 0..16 { w[i] = u32::from_be_bytes([chunk[i*4], chunk[i*4+1], chunk[i*4+2], chunk[i*4+3]]); }
for i in 16..80 { w[i] = (w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]).rotate_left(1); }
let (mut a, mut b, mut c, mut d, mut e) = (h0, h1, h2, h3, h4);
for i in 0..80 {
let (f, k) = match i {
0..=19 => ((b & c) | ((!b) & d), 0x5A827999),
20..=39 => (b ^ c ^ d, 0x6ED9EBA1),
40..=59 => ((b & c) | (b & d) | (c & d), 0x8F1BBCDC),
_ => (b ^ c ^ d, 0xCA62C1D6),
};
let temp = a.rotate_left(5).wrapping_add(f).wrapping_add(e).wrapping_add(k).wrapping_add(w[i]);
e = d; d = c; c = b.rotate_left(30); b = a; a = temp;
}
h0 = h0.wrapping_add(a); h1 = h1.wrapping_add(b);
h2 = h2.wrapping_add(c); h3 = h3.wrapping_add(d); h4 = h4.wrapping_add(e);
}
format!("{:08x}{:08x}{:08x}{:08x}{:08x}", h0, h1, h2, h3, h4)
}
// --- SHA-256 ENGINE ---
fn sha256(data: &[u8]) -> String {
let mut h: [u32; 8] = [0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19];
let mut padded = data.to_vec();
let bit_len = (padded.len() as u64) * 8;
padded.push(0x80);
while (padded.len() * 8) % 512 != 448 { padded.push(0); }
padded.extend_from_slice(&bit_len.to_be_bytes());
for chunk in padded.chunks(64) {
let mut w = [0u32; 64];
for i in 0..16 { w[i] = u32::from_be_bytes([chunk[i*4], chunk[i*4+1], chunk[i*4+2], chunk[i*4+3]]); }
for i in 16..64 {
let s0 = w[i-15].rotate_right(7) ^ w[i-15].rotate_right(18) ^ (w[i-15] >> 3);
let s1 = w[i-2].rotate_right(17) ^ w[i-2].rotate_right(19) ^ (w[i-2] >> 10);
w[i] = w[i-16].wrapping_add(s0).wrapping_add(w[i-7]).wrapping_add(s1);
}
let [mut a, mut b, mut c, mut d, mut e, mut f, mut g, mut h_val] = h;
for i in 0..64 {
let s1 = e.rotate_right(6) ^ e.rotate_right(11) ^ e.rotate_right(25);
let ch = (e & f) ^ ((!e) & g);
let temp1 = h_val.wrapping_add(s1).wrapping_add(ch).wrapping_add(SHA256_K[i]).wrapping_add(w[i]);
let s0 = a.rotate_right(2) ^ a.rotate_right(13) ^ a.rotate_right(22);
let maj = (a & b) ^ (a & c) ^ (b & c);
let temp2 = s0.wrapping_add(maj);
h_val = g; g = f; f = e; e = d.wrapping_add(temp1); d = c; c = b; b = a; a = temp1.wrapping_add(temp2);
}
h = [h[0].wrapping_add(a), h[1].wrapping_add(b), h[2].wrapping_add(c), h[3].wrapping_add(d),
h[4].wrapping_add(e), h[5].wrapping_add(f), h[6].wrapping_add(g), h[7].wrapping_add(h_val)];
}
h.iter().map(|x| format!("{:08x}", x)).collect()
}
// --- POOL STRUCTURES ---
pub struct BlockTemplate {
pub version: u32,
pub prev_block: String,
pub merkle_root: String,
pub pool_target: String,
}
pub struct DecentralizedPoolNode {
pub miner_id: String,
pub current_template: Arc<Mutex<BlockTemplate>>,
pub shares_submitted: u64,
}
impl DecentralizedPoolNode {
pub fn new(miner_id: &str, initial_template: BlockTemplate) -> Self {
Self {
miner_id: miner_id.to_string(),
current_template: Arc::new(Mutex::new(initial_template)),
shares_submitted: 0,
}
}
pub fn verify_incoming_share(&mut self, nonce: u64) -> bool {
let template = self.current_template.lock().unwrap();
let payload = format!("{}{}{}{}", template.version, template.prev_block, template.merkle_root, nonce);
let intermediate_hash = sha256(payload.as_bytes());
let final_hash = sha256(intermediate_hash.as_bytes());
if final_hash.starts_with(&template.pool_target) {
self.shares_submitted += 1;
true
} else {
false
}
}
}
// --- BYZANTINE FEE ENGINE TYPES ---
#[derive(Debug, Clone, Copy)]
pub struct ByzantineFeeProposal {
pub node_id: usize,
pub reported_fee_rate: u64,
pub is_byzantine: bool,
}
pub fn calculate_bft_median_fee(mut proposals: Vec<ByzantineFeeProposal>) -> u64 {
let n = proposals.len();
if n == 0 { return 1; }
let f = n / 3;
proposals.sort_by_key(|p| p.reported_fee_rate);
let valid_range = &proposals[f..(n - f)];
let median_index = valid_range.len() / 2;
valid_range[median_index].reported_fee_rate
}
// --- TIME & FEE NETWORK STATE MACHINE ---
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
pub enum SyncStage { Hour, Minute, Second, FeeConsensus, NonceGrind1Bit, NonceGrind2Bit }
pub struct SyncNode {
pub id: usize,
pub adjustment: Duration,
pub stage: SyncStage,
pub start_nonce: u64,
pub nonce: u64,
pub success: bool,
pub last_hash: String,
pub internal_fee_estimation: u64,
pub is_byzantine_adversary: bool,
}
impl SyncNode {
pub fn new(id: usize, offset_sec: i64, total_nodes: usize, is_adversary: bool) -> Self {
let stride = u64::MAX / (total_nodes as u64);
let start_nonce = (id as u64) * stride;
let fee_basis = if is_adversary { 9999 } else { 15 + (id as u64 % 5) * 5 };
Self {
id,
adjustment: Duration::seconds(offset_sec),
stage: SyncStage::Hour,
start_nonce,
nonce: start_nonce,
success: false,
last_hash: String::from("0000000000000000000000000000000000000000"),
internal_fee_estimation: fee_basis,
is_byzantine_adversary: is_adversary,
}
}
pub fn get_logical_utc(&self) -> DateTime<Utc> {
Utc::now() + self.adjustment
}
pub fn broadcast_fee_proposal(&self) -> ByzantineFeeProposal {
ByzantineFeeProposal {
node_id: self.id,
reported_fee_rate: self.internal_fee_estimation,
is_byzantine: self.is_byzantine_adversary,
}
}
pub fn update_stage(&mut self, spread: i64, all_same_minute: bool, global_fee_agreed: bool, global_1bit_reached: bool) {
match self.stage {
SyncStage::Hour => if spread < 3600 { self.stage = SyncStage::Minute; },
SyncStage::Minute => if spread < 60 { self.stage = SyncStage::Second; },
SyncStage::Second => if spread == 0 && all_same_minute { self.stage = SyncStage::FeeConsensus; },
SyncStage::FeeConsensus => if global_fee_agreed { self.stage = SyncStage::NonceGrind1Bit; },
SyncStage::NonceGrind1Bit => {
if spread > 0 || !all_same_minute {
self.stage = SyncStage::Second; self.success = false; self.nonce = self.start_nonce;
} else if global_1bit_reached {
self.stage = SyncStage::NonceGrind2Bit; self.success = false;
}
},
SyncStage::NonceGrind2Bit => {
if spread > 0 || !all_same_minute {
self.stage = SyncStage::Second; self.success = false; self.nonce = self.start_nonce;
}
}
}
}
pub fn grind_nonce(&mut self, target: &str, template: &BlockTemplate, agreed_network_fee: u64) {
let time = self.get_logical_utc();
let minute = time.minute();
loop {
let input = format!(
"BLOCK-{}-{}-{}-{}-FEE:{}",
template.prev_block,
template.merkle_root,
minute,
self.nonce,
agreed_network_fee
);
let hash = if target == "00" {
let round1 = sha256(input.as_bytes());
sha256(round1.as_bytes())
} else {
git_sha1(input.as_bytes())
};
if target == "00" {
if hash.starts_with("00") {
self.last_hash = hash; self.success = true; break;
} else if hash.starts_with("0") {
self.last_hash = hash; self.nonce += 1; break;
}
} else {
self.last_hash = hash;
if self.last_hash.starts_with(target) { self.success = true; } else { self.nonce += 1; }
break;
}
self.nonce += 1;
}
}
}
fn get_median_diff(timestamps: &[i64], current: i64) -> i64 {
let mut diffs: Vec<i64> = timestamps.iter().map(|t| t - current).collect();
diffs.sort();
diffs[diffs.len() / 2]
}
// --- MAIN RUNTIME LOOP ---
fn main() {
let total_nodes = 10;
let initial_job = BlockTemplate {
version: 4,
prev_block: "000000000000000000021c33f24bf7aef12d".to_string(),
merkle_root: "94b8e19c20cb3ffbb123a".to_string(),
pool_target: "00".to_string(),
};
let mut pool_node = DecentralizedPoolNode::new("pleb_pool_partitioner", initial_job);
println!("Decentralized Sharded Pool Node Active. ID: {}", pool_node.miner_id);
let mut nodes: Vec<SyncNode> = (0..total_nodes).map(|i| {
let offset = match i { 0..=2 => 10, 3..=5 => 5, _ => 2 };
let is_byzantine = i < 2;
SyncNode::new(i, offset, total_nodes, is_byzantine)
}).collect();
let mut round = 1;
let mut final_consensus_fee: u64 = 0;
loop {
let current_times: Vec<DateTime<Utc>> = nodes.iter().map(|n| n.get_logical_utc()).collect();
let timestamps: Vec<i64> = current_times.iter().map(|t| t.timestamp()).collect();
let spread = (timestamps.iter().max().unwrap() - timestamps.iter().min().unwrap()).abs();
let all_same_minute = current_times.iter().all(|t| t.minute() == current_times[0].minute());
let proposals: Vec<ByzantineFeeProposal> = nodes.iter().map(|n| n.broadcast_fee_proposal()).collect();
let calculated_bft_fee = calculate_bft_median_fee(proposals);
let global_fee_agreed = nodes.iter().all(|n| n.stage >= SyncStage::FeeConsensus);
let global_1bit_reached = nodes.iter().all(|n| n.stage == SyncStage::NonceGrind1Bit && n.success);
let has_consensus = {
let active_template = pool_node.current_template.lock().unwrap();
println!(
"\n--- [ROUND {:03}] Spread:{}s | TimeMinConsensus:{} | Secure BFT Fee: {} sat/vB ---",
round, spread, all_same_minute, calculated_bft_fee
);
final_consensus_fee = calculated_bft_fee;
for i in 0..total_nodes {
// Save original local expectation for logging outputs before phase transition overrides it
let local_untrusted_fee = nodes[i].internal_fee_estimation;
nodes[i].update_stage(spread, all_same_minute, global_fee_agreed, global_1bit_reached);
match nodes[i].stage {
SyncStage::Hour | SyncStage::Minute | SyncStage::Second => {
let d = get_median_diff(&timestamps, timestamps[i]);
let step = if nodes[i].stage == SyncStage::Second { d.signum() } else { d / 2 };
nodes[i].adjustment = nodes[i].adjustment + Duration::seconds(step);
},
SyncStage::FeeConsensus => {
nodes[i].internal_fee_estimation = calculated_bft_fee;
},
SyncStage::NonceGrind1Bit => {
if !nodes[i].success {
nodes[i].grind_nonce("0", &active_template, calculated_bft_fee);
}
}
SyncStage::NonceGrind2Bit => {
if !nodes[i].success {
nodes[i].grind_nonce("00", &active_template, calculated_bft_fee);
}
}
};
let mark = if nodes[i].success { "SOLVED " } else { "MINING" };
let role = if nodes[i].is_byzantine_adversary { "MALICIOUS" } else { "HONEST " };
// ADDED: Prints internal untrusted local fee rate side-by-side with the agreed BFT fee rate target
println!(
"N{:02} [{}] | Stage:{} | Time: {} | LocalFee: {:4} sat/vB | BftFee: {:4} sat/vB | Nonce: {:x} | {} | HASH: {}",
i, role, nodes[i].stage as u8, current_times[i].format("%H:%M:%S"),
local_untrusted_fee, nodes[i].internal_fee_estimation, nodes[i].nonce, mark, nodes[i].last_hash
);
}
nodes.iter().all(|n| n.stage == SyncStage::NonceGrind2Bit && n.success)
};
if has_consensus {
for i in 0..total_nodes {
pool_node.verify_incoming_share(nodes[i].nonce);
}
println!("\n>>> SUCCESS: BYZANTINE FEE CONSENSUS COMPLETED AND BOUND TO NONCE PAYLOAD <<<");
println!("Final Network Agreed Fee Rate Base: {} sat/vB", final_consensus_fee);
break;
}
round += 1;
std::thread::sleep(StdDuration::from_millis(15));
if round > 1000 { break; }
}
}
// --- TESTING SUITE ---
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_byzantine_fee_filtering_outliers() {
let proposals = vec![
ByzantineFeeProposal { node_id: 0, reported_fee_rate: 9999, is_byzantine: true },
ByzantineFeeProposal { node_id: 1, reported_fee_rate: 1, is_byzantine: true },
ByzantineFeeProposal { node_id: 2, reported_fee_rate: 25, is_byzantine: false },
ByzantineFeeProposal { node_id: 3, reported_fee_rate: 30, is_byzantine: false },
ByzantineFeeProposal { node_id: 4, reported_fee_rate: 20, is_byzantine: false },
];
let settled_fee = calculate_bft_median_fee(proposals);
assert!(settled_fee >= 20 && settled_fee <= 30);
}
}
@RandyMcMillan

Copy link
Copy Markdown
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment