summaryrefslogtreecommitdiffstats
path: root/examples/consensus_demo.rs
diff options
context:
space:
mode:
authorgabrix73 <gabriel1@frozenstar.info>2026-06-01 18:41:36 +0200
committergabrix73 <gabriel1@frozenstar.info>2026-06-01 18:41:36 +0200
commit9f5d864d533ce86459e654f5d78212933c0269ea (patch)
tree4b71e8c7ab4e78da93e5f3164803da4de68c7031 /examples/consensus_demo.rs
downloadonioncoin-9f5d864d533ce86459e654f5d78212933c0269ea.tar.gz
onioncoin-9f5d864d533ce86459e654f5d78212933c0269ea.tar.xz
onioncoin-9f5d864d533ce86459e654f5d78212933c0269ea.zip
Initial commit: OnionCoin prototype with Proof-of-Relay consensusHEADv0.1.0main
OnionCoin is a privacy cryptocurrency that rewards Tor relay operators through a unique Proof-of-Contribution consensus mechanism. Core Features: - Proof-of-Relay: 30% of block rewards go to Tor operators - Native .onion node identity (no IP exposure) - Temporal obfuscation protocols - Dandelion++ over Tor propagation - Native inheritance system with dead man's switch Technical Stack: - Rust workspace with 8 crates - Ed25519/X25519 cryptography - arti (Rust Tor client) integration planned - 10 minute block time, 5-10 TPS design Status: Prototype - Consensus logic complete with passing tests (30/33) - Network layer conceptual design complete - Tor integration pending - Testnet launch planned Q3 2026 License: MIT Author: Gabriele Salati (virebent) Contact: g48rix@gmail.com Website: https://www.gabrielesalati.eu Repository: https://git.virebent.art/virebent/onioncoin
Diffstat (limited to 'examples/consensus_demo.rs')
-rw-r--r--examples/consensus_demo.rs271
1 files changed, 271 insertions, 0 deletions
diff --git a/examples/consensus_demo.rs b/examples/consensus_demo.rs
new file mode 100644
index 0000000..7017f1e
--- /dev/null
+++ b/examples/consensus_demo.rs
@@ -0,0 +1,271 @@
+/// Demonstration of OnionCoin's Proof-of-Contribution consensus
+///
+/// Shows how validators earn rewards through:
+/// - Stake (40%)
+/// - Tor relay work (30%) ← UNIQUE!
+/// - Bandwidth (15%)
+/// - Uptime (10%)
+/// - Storage (5%)
+
+use onioncoin_consensus::*;
+use onioncoin_consensus::proof_of_contribution::ScoreWeights;
+
+fn main() {
+ println!("=== OnionCoin Proof-of-Contribution Demo ===\n");
+
+ demo_validator_tiers();
+ println!();
+
+ demo_contribution_scoring();
+ println!();
+
+ demo_relay_proof();
+ println!();
+
+ demo_validator_selection();
+ println!();
+
+ demo_genesis_mining();
+}
+
+fn demo_validator_tiers() {
+ println!("šŸŽÆ VALIDATOR TIERS");
+ println!("==================");
+
+ let tiers = [
+ ValidatorTier::Micro,
+ ValidatorTier::Light,
+ ValidatorTier::Standard,
+ ValidatorTier::Power,
+ ];
+
+ println!("ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”");
+ println!("│ Tier │ Min Stake │ Hardware │ Monthly Return │");
+ println!("ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤");
+
+ for tier in &tiers {
+ println!(
+ "│ {:11} │ {:10} ONC │ {:18} │ ~{:13} ONC │",
+ format!("{:?}", tier),
+ tier.min_stake(),
+ match tier {
+ ValidatorTier::Micro => "Raspberry Pi Zero",
+ ValidatorTier::Light => "Raspberry Pi 4",
+ ValidatorTier::Standard => "Desktop PC/VPS",
+ ValidatorTier::Power => "Server 24/7",
+ },
+ format!("{:.1}", tier.expected_monthly_return())
+ );
+ }
+
+ println!("ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜");
+ println!("\nāœ… Even a Raspberry Pi Zero can validate!");
+}
+
+fn demo_contribution_scoring() {
+ println!("šŸ“Š CONTRIBUTION SCORING");
+ println!("======================");
+
+ // Scenario 1: Whale with just stake (lazy validator)
+ let whale = Validator::new([1u8; 32], 10000, "whale.onion".to_string(), 0).unwrap();
+ let whale_score = ProofOfContribution::calculate(
+ &whale,
+ None, // No relay work
+ &BandwidthMetrics::new(),
+ &UptimeMetrics::new(0),
+ &StorageMetrics::new(),
+ );
+
+ println!("Scenario 1: Whale Validator (10,000 ONC stake, no work)");
+ println!("{}", whale_score.score.breakdown());
+
+ println!("\n─────────────────────────────────────────────────────\n");
+
+ // Scenario 2: Micro validator with relay work (active participant)
+ let micro = Validator::new([2u8; 32], 10, "micro.onion".to_string(), 0).unwrap();
+
+ // Excellent relay metrics
+ let mut relay_metrics = RelayMetrics::new();
+ relay_metrics.bytes_relayed = 100 * 1024 * 1024 * 1024; // 100 GB!
+ relay_metrics.unique_circuits = 200;
+ relay_metrics.packets_relayed = 1_000_000;
+ relay_metrics.avg_latency_ms = 500;
+
+ let relay_proof = RelayProof::new([2u8; 32], 0, 3600, relay_metrics);
+
+ // Good bandwidth
+ let mut bandwidth = BandwidthMetrics::new();
+ bandwidth.update(10_000_000, 10_000_000, 100);
+
+ // Great uptime
+ let mut uptime = UptimeMetrics::new(0);
+ for i in 1..=1000 {
+ uptime.record_heartbeat(i * 60);
+ }
+
+ // Some storage
+ let mut storage = StorageMetrics::new();
+ storage.update(20 * 1024 * 1024 * 1024, 10 * 1024 * 1024 * 1024, 1000, 10000);
+
+ let micro_score = ProofOfContribution::calculate(
+ &micro,
+ Some(&relay_proof),
+ &bandwidth,
+ &uptime,
+ &storage,
+ );
+
+ println!("Scenario 2: Micro Validator (10 ONC stake, LOTS of work)");
+ println!("{}", micro_score.score.breakdown());
+
+ println!("\nšŸŽÆ KEY INSIGHT:");
+ println!(" Whale total score: {:.3}", whale_score.total_score());
+ println!(" Micro total score: {:.3}", micro_score.total_score());
+ println!("\n Micro validator is {}% as competitive as whale!",
+ (micro_score.total_score() / whale_score.total_score() * 100.0) as i32);
+ println!(" šŸ’” OnionCoin rewards WORK, not just wealth!");
+}
+
+fn demo_relay_proof() {
+ println!("🌐 PROOF-OF-RELAY (OnionCoin's UNIQUE Feature)");
+ println!("==============================================");
+
+ println!("Relay Node Activity:");
+ println!(" - Relayed: 50 GB of OnionCoin traffic");
+ println!(" - Circuits: 150 unique Tor circuits");
+ println!(" - Packets: 500,000");
+ println!(" - Latency: 800ms average");
+
+ let mut metrics = RelayMetrics::new();
+ metrics.bytes_relayed = 50 * 1024 * 1024 * 1024;
+ metrics.unique_circuits = 150;
+ metrics.packets_relayed = 500_000;
+ metrics.avg_latency_ms = 800;
+
+ let proof = RelayProof::new([42u8; 32], 0, 3600, metrics);
+
+ println!("\nRelay Proof:");
+ println!(" - Valid: {}", proof.verify());
+ println!(" - Quality Score: {:.2}", proof.metrics.quality_score());
+ println!(" - Reward: {} ONC", proof.calculate_reward());
+
+ println!("\nāœ… NO OTHER CRYPTOCURRENCY REWARDS TOR RELAY WORK!");
+}
+
+fn demo_validator_selection() {
+ println!("šŸŽ² VALIDATOR SELECTION");
+ println!("=====================");
+
+ let mut registry = ValidatorRegistry::new();
+
+ // Create diverse validators
+ let validators_data = vec![
+ ("whale.onion", 10000, 0.3), // High stake, low work
+ ("worker.onion", 100, 0.8), // Low stake, high work
+ ("balanced.onion", 1000, 0.6), // Balanced
+ ];
+
+ let mut validators = Vec::new();
+ for (i, (addr, stake, score)) in validators_data.iter().enumerate() {
+ let pubkey = [(i + 1) as u8; 32];
+ let validator = Validator::new(pubkey, *stake, addr.to_string(), 0).unwrap();
+ registry.register(validator.clone()).unwrap();
+ validators.push((validator, *score));
+ }
+
+ println!("Validators:");
+ for (validator, score) in &validators {
+ println!(" - {}: {} ONC (score: {:.2})",
+ validator.onion_address,
+ validator.stake,
+ score);
+ }
+
+ // Create contribution proofs
+ let candidates: Vec<_> = validators
+ .iter()
+ .map(|(v, score)| {
+ let poc = create_mock_poc(v.pubkey, *score);
+ (v, poc)
+ })
+ .collect();
+
+ let selector = ValidatorSelector::default();
+
+ println!("\nSelection Simulation (1000 rounds):");
+ let mut selection_counts = std::collections::HashMap::new();
+
+ for height in 0..1000 {
+ let prev_hash = [height as u8; 32];
+ if let Some(selected) = selector.select_validator(&candidates, &prev_hash, height) {
+ *selection_counts.entry(selected).or_insert(0) += 1;
+ }
+ }
+
+ for (validator, _) in &validators {
+ let count = selection_counts.get(&validator.pubkey).unwrap_or(&0);
+ let percentage = (*count as f64 / 1000.0) * 100.0;
+ println!(" - {}: selected {} times ({:.1}%)",
+ validator.onion_address,
+ count,
+ percentage);
+ }
+
+ println!("\nāœ… High-work validators get selected more often!");
+}
+
+fn demo_genesis_mining() {
+ println!("🌱 GENESIS MINING (Fair Launch)");
+ println!("================================");
+
+ let config = GenesisConfig::default();
+ let mut genesis = GenesisMining::new(config.clone(), 0);
+
+ println!("Genesis Phase:");
+ println!(" - Duration: 6 months");
+ println!(" - Total Supply: 1,000,000 ONC");
+ println!(" - Distribution: 100% to Tor relay operators");
+ println!(" - NO pre-mine, NO ICO, completely FAIR\n");
+
+ // Simulate 3 relay operators
+ let operators = vec![
+ ("Early adopter (day 1)", [1u8; 32], "early.onion", 0, 100 * 1024 * 1024 * 1024u64),
+ ("Mid participant (month 2)", [2u8; 32], "mid.onion", 60 * 24 * 3600, 80 * 1024 * 1024 * 1024),
+ ("Late joiner (month 4)", [3u8; 32], "late.onion", 120 * 24 * 3600, 50 * 1024 * 1024 * 1024),
+ ];
+
+ for (name, pubkey, addr, reg_time, bytes) in &operators {
+ genesis.register_relay(*pubkey, addr.to_string(), *reg_time);
+ genesis.record_relay_activity(pubkey, *bytes, 86400 * 30); // 30 days uptime
+
+ let rewards = genesis.calculate_rewards(pubkey, config.duration_seconds);
+ println!("{}", name);
+ println!(" - Relayed: {} GB", bytes / (1024 * 1024 * 1024));
+ println!(" - Rewards: {} ONC", rewards);
+ }
+
+ let stats = genesis.stats();
+ println!("\nGenesis Stats:");
+ println!(" - Total relay nodes: {}", stats.total_relay_nodes);
+ println!(" - Total relayed: {} GB", stats.total_bytes_relayed / (1024 * 1024 * 1024));
+
+ println!("\nāœ… Early participants get bonus, but everyone can join!");
+}
+
+// Helper function
+fn create_mock_poc(pubkey: [u8; 32], total_score: f64) -> ProofOfContribution {
+ let score = ContributionScore {
+ stake_score: total_score * 0.4,
+ relay_score: total_score * 0.3,
+ bandwidth_score: total_score * 0.15,
+ uptime_score: total_score * 0.1,
+ storage_score: total_score * 0.05,
+ weights: ScoreWeights::default(),
+ };
+
+ ProofOfContribution {
+ validator_pubkey: pubkey,
+ score,
+ timestamp: 0,
+ }
+}