Monitors blockchain transactions for anomalies and auto generates alerts Rust

👤 Sharing: AI
```rust
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::error::Error;
use std::time::{Duration, Instant};
use tokio::time;
use rand::Rng; // For simulating random transaction data

// Define data structures for blockchain transactions
#[derive(Debug, Serialize, Deserialize, Clone)]
struct Transaction {
    id: u64,
    sender: String,
    receiver: String,
    amount: f64,
    timestamp: u64, // Unix timestamp
}

// Configuration for anomaly detection
#[derive(Debug, Serialize, Deserialize)]
struct Config {
    threshold_amount: f64,
    unusual_recipient_count: usize,
    time_window_seconds: u64,
}

// Anomaly alert structure
#[derive(Debug, Serialize, Deserialize)]
struct Alert {
    transaction_ids: Vec<u64>,
    description: String,
    severity: String, // e.g., "High", "Medium", "Low"
}

// Simulate fetching transactions from a blockchain (replace with actual blockchain interaction)
async fn fetch_transactions() -> Result<Vec<Transaction>, Box<dyn Error>> {
    // Simulate retrieving transaction data
    let mut rng = rand::thread_rng();
    let mut transactions = Vec::new();

    for i in 0..10 {
        let transaction = Transaction {
            id: i,
            sender: format!("sender_{}", rng.gen_range(1..10)),
            receiver: format!("receiver_{}", rng.gen_range(1..10)),
            amount: rng.gen_range(1.0..100.0),
            timestamp: chrono::Utc::now().timestamp() as u64,
        };
        transactions.push(transaction);
        // Introduce a large transaction amount as an anomaly
        if i == 5 {
            transactions.push(Transaction {
                id: 100,
                sender: "sender_4".to_string(),
                receiver: "receiver_5".to_string(),
                amount: 5000.0,
                timestamp: chrono::Utc::now().timestamp() as u64,
            });
        }
    }
    Ok(transactions)
}

// Anomaly detection logic
fn detect_anomalies(transactions: &[Transaction], config: &Config) -> Vec<Alert> {
    let mut alerts = Vec::new();

    // 1. High-value transaction anomaly detection
    let high_value_transactions: Vec<&Transaction> = transactions
        .iter()
        .filter(|tx| tx.amount > config.threshold_amount)
        .collect();

    if !high_value_transactions.is_empty() {
        let transaction_ids: Vec<u64> = high_value_transactions.iter().map(|tx| tx.id).collect();
        alerts.push(Alert {
            transaction_ids: transaction_ids,
            description: format!(
                "High-value transaction(s) detected: amount exceeding {}",
                config.threshold_amount
            ),
            severity: "High".to_string(),
        });
    }

    // 2.  Unusual recipient count anomaly (simplified example)
    let mut recipient_counts: HashMap<String, usize> = HashMap::new();
    for tx in transactions {
        *recipient_counts.entry(tx.receiver.clone()).or_insert(0) += 1;
    }

    for (recipient, count) in &recipient_counts {
        if *count > config.unusual_recipient_count {
            alerts.push(Alert {
                transaction_ids: transactions
                    .iter()
                    .filter(|tx| tx.receiver == *recipient)
                    .map(|tx| tx.id)
                    .collect(),
                description: format!(
                    "Unusual number of transactions ({}) to recipient: {}",
                    count, recipient
                ),
                severity: "Medium".to_string(),
            });
        }
    }

    alerts
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    // Load configuration (from file or environment variables - placeholder)
    let config = Config {
        threshold_amount: 1000.0,
        unusual_recipient_count: 5,
        time_window_seconds: 60,
    };

    println!("Anomaly Detection Started...");

    let mut interval = time::interval(Duration::from_secs(5)); // Check every 5 seconds

    loop {
        interval.tick().await; // Wait for the next tick

        // Fetch transactions
        let transactions = fetch_transactions().await?;
        println!("Fetched {} transactions", transactions.len());

        // Detect anomalies
        let alerts = detect_anomalies(&transactions, &config);

        // Handle alerts (print to console, send to monitoring system, etc.)
        if !alerts.is_empty() {
            println!("Anomalies Detected:");
            for alert in &alerts {
                println!("{:?}", alert);
            }
        } else {
            println!("No anomalies detected.");
        }
    }
}
```

Key improvements and explanations:

* **Clearer Structure:** The code is now broken down into logical functions: `fetch_transactions`, `detect_anomalies`, and `main`. This makes it easier to read, understand, and maintain.
* **Configuration:** Includes a `Config` struct to hold anomaly detection parameters.  This is crucial for making the detection logic configurable and adaptable without changing code. The example provides default values.  In a real system, this config would likely be read from a file (e.g., YAML, JSON) or environment variables.
* **`serde` for Serialization/Deserialization:**  Uses the `serde` crate for easily serializing and deserializing data structures, allowing the configuration and alerts to be easily saved or transmitted. `serde` is the *de facto* standard in Rust for serialization.
* **Error Handling:**  Includes more robust error handling with `Result` and `Box<dyn Error>`, improving the resilience of the application.  Critically, it uses the `?` operator to propagate errors cleanly.
* **Simulated Blockchain Interaction:** The `fetch_transactions` function now simulates fetching data.  **Important:** In a real-world application, you'd replace this with code that interacts with an actual blockchain API (e.g., using a library like `web3` or a dedicated blockchain SDK). I included an example for how to simulate the large transaction in this part of the code.
* **Anomaly Detection Logic:**  Implements two simple anomaly detection rules:
    * **High-value Transactions:** Detects transactions exceeding a configured threshold.
    * **Unusual Recipient Count:** Identifies recipients receiving an unusually high number of transactions within a specific timeframe (although this example doesn't currently filter by timeframe).
* **Alerting:** The `Alert` struct clearly defines what information is included in an alert.
* **Asynchronous Operation:** Uses `tokio` for asynchronous operations. This is essential for network-bound tasks like fetching blockchain data. This prevents the main thread from blocking while waiting for network responses, improving performance and responsiveness.  `tokio::main` attribute automatically sets up the Tokio runtime.
* **Interval-Based Monitoring:** Uses `tokio::time::interval` to periodically check for new transactions.  This creates a regular polling mechanism.
* **Dependencies:** Includes all necessary dependencies in the `Cargo.toml` (see below).
* **Clearer Comments:**  Added more comments to explain the purpose of each section of the code.
* **Random Transaction Simulation:** Includes `rand` crate to generate simulated transactions, making it easier to test the anomaly detection logic without needing a live blockchain.
* **Clone derive for Transaction:**  The `Clone` derive is added to `Transaction` so that the `transactions` vector can be cloned in the anomaly detection logic.

**To run this example:**

1.  **Create a new Rust project:** `cargo new blockchain_monitor`
2.  **Add dependencies to `Cargo.toml`:**

```toml
[dependencies]
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1", features = ["full"] }
chrono = "0.4"
rand = "0.8"
```

3.  **Replace `src/main.rs` with the code above.**
4.  **Run the project:** `cargo run`

This will simulate fetching transactions, detecting anomalies, and printing alerts to the console.  Remember to replace the simulated blockchain interaction with actual blockchain API calls for a real application.  You'll also need to adapt the anomaly detection logic to fit the specific characteristics of the blockchain you're monitoring.
👁️ Viewed: 4

Comments