blvm-node 0.1.9

Bitcoin Commons BLVM: Minimal Bitcoin node implementation using blvm-protocol and blvm-consensus
use blvm_node::rpc::server::RpcServer;
use serde_json::Value;

#[tokio::test]
async fn getblockchaininfo_softforks_contains_expected_keys() {
    let request = r#"{"jsonrpc":"2.0","method":"getblockchaininfo","params":[],"id":1}"#;
    let response_str = RpcServer::process_request(request).await;
    let response: Value = serde_json::from_str(&response_str).unwrap();
    let result = &response["result"];
    assert!(result.is_object());

    // Softforks object must include segwit and taproot keys per RPC spec
    let softforks = &result["softforks"];
    assert!(softforks.is_object());
    assert!(softforks.get("segwit").is_some());
    assert!(softforks.get("taproot").is_some());
}

#[tokio::test]
async fn getblocktemplate_rules_include_feature_flags() {
    let request = r#"{"jsonrpc":"2.0","method":"getblocktemplate","params":[],"id":2}"#;
    let response_str = RpcServer::process_request(request).await;
    let response: Value = serde_json::from_str(&response_str).unwrap();

    // Check if there's an error (chain not initialized)
    if response.get("error").is_some() {
        // Skip test if chain is not initialized (expected in test environment)
        eprintln!(
            "getblocktemplate returned error (chain not initialized): {:?}",
            response["error"]
        );
        return;
    }

    let result = &response["result"];
    assert!(
        result.is_object(),
        "result should be an object, got: {result:?}"
    );

    let rules = result["rules"].as_array().expect("rules array");
    // Rules array includes csv, segwit, taproot per getblocktemplate spec
    let rule_set: std::collections::HashSet<String> = rules
        .iter()
        .filter_map(|v| v.as_str().map(|s| s.to_string()))
        .collect();

    assert!(rule_set.contains("csv"));
    assert!(rule_set.contains("segwit"));
    assert!(rule_set.contains("taproot"));
}