Rust闪电网络高效同步库lightning-rapid-gossip-sync的使用:实现比特币节点快速数据同步与网络拓扑更新

Rust闪电网络高效同步库lightning-rapid-gossip-sync的使用:实现比特币节点快速数据同步与网络拓扑更新

lightning-rapid-gossip-sync

这个crate提供了快速同步gossip图的功能,主要面向移动客户端。其服务器对应部分是rapid-gossip-sync-server仓库。

使用方法

要从头开始启动Rapid Gossip Sync,需要从RGS服务器实例获取初始时间戳为0的快照。

使用RapidGossipSync实例应用该快照将提取并获取要从服务器实例请求的后续时间戳。方法sync_network_graph_with_file_pathupdate_network_graphupdate_network_graph_no_std都返回Result<u32, GraphSyncError>,成功时的u32值就是用于下次服务器请求的时间戳。

请注意,运行这些方法也会更新存储在NetworkGraph对象中的时间戳,可以通过调用get_last_rapid_gossip_sync_timestamp轻松获取,因此使用RGS不会对存储网络图之外的任何额外缓存要求。

机制

(假设的)服务器发送包含gossip数据的压缩gossip响应。gossip数据格式紧凑,省略签名并在已知先前通道更新时进行机会性增量。

完整示例代码

use lightning::ln::msgs::NetAddress;
use lightning::routing::gossip::NetworkGraph;
use lightning_rapid_gossip_sync::RapidGossipSync;

fn main() {
    // 创建网络图实例
    let network_graph = NetworkGraph::new(bitcoin::network::constants::Network::Bitcoin);
    
    // 创建RapidGossipSync实例
    let rapid_sync = RapidGossipSync::new(&network_graph);
    
    // 假设这是从RGS服务器获取的快照数据
    let snapshot_data = vec![/* 压缩的gossip数据 */];
    
    // 同步网络图
    let result = rapid_sync.sync_network_graph(&snapshot_data);
    
    match result {
        Ok(next_timestamp) => {
            println!("同步成功,下次请求时间戳: {}", next_timestamp);
            
            // 获取最后同步时间戳
            let last_sync_timestamp = network_graph.get_last_rapid_gossip_sync_timestamp();
            println!("最后同步时间戳: {}", last_sync_timestamp);
        },
        Err(e) => {
            eprintln!("同步失败: {:?}", e);
        }
    }
}

性能

考虑到该工具的主要目的是更快地同步图,我们提供了一些不同delta集的示例。这些示例计算于2024年8月,网络图包含80,000个通道公告和160,000个定向通道更新。

处理时间是在iPhone 15 Pro上100次迭代的平均值。

完整同步
消息长度 3.3 MB
Gzip压缩消息长度 1.5 MB
客户端处理时间 407 ms
一周前同步
消息长度 1.7 MB
Gzip压缩消息长度 566 kB
客户端处理时间 283 ms
一天前同步
消息长度 210 kB
Gzip压缩消息长度 99 kB
客户端处理时间 26 ms

扩展完整示例代码

以下是一个更完整的示例,包含从文件加载数据和定期更新的逻辑:

use std::fs;
use std::time::{SystemTime, UNIX_EPOCH};
use lightning::routing::gossip::NetworkGraph;
use lightning_rapid_gossip_sync::RapidGossipSync;
use bitcoin::network::constants::Network;

// 从文件加载快照数据
fn load_snapshot_data(file_path: &str) -> Vec<u8> {
    fs::read(file_path).expect("无法读取快照文件")
}

// 获取当前时间戳(秒)
fn current_timestamp() -> u32 {
    SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .unwrap()
        .as_secs() as u32
}

fn main() {
    // 初始化网络图(比特币主网)
    let network_graph = NetworkGraph::new(Network::Bitcoin);
    let rapid_sync = RapidGossipSync::new(&network_graph);

    // 初始同步(时间戳0)
    let initial_snapshot = load_snapshot_data("initial_snapshot.bin");
    let mut last_timestamp = match rapid_sync.sync_network_graph(&initial_snapshot) {
        Ok(ts) => {
            println!("初始同步成功,下次时间戳: {}", ts);
            ts
        }
        Err(e) => {
            eprintln!("初始同步失败: {:?}", e);
            return;
        }
    };

    // 模拟定期更新
    for _ in 0..5 {
        // 模拟从服务器获取增量数据(根据最后时间戳)
        let delta_file = format!("delta_{}.bin", last_timestamp);
        let delta_data = load_snapshot_data(&delta_file);
        
        // 更新网络图
        match rapid_sync.update_network_graph(&delta_data) {
            Ok(new_timestamp) => {
                println!("增量更新成功,新时间戳: {}", new_timestamp);
                last_timestamp = new_timestamp;
                
                // 可以在这里添加业务逻辑,如路由计算等
                let current_ts = current_timestamp();
                println!("当前系统时间戳: {},最后同步时间差: {}秒", 
                    current_ts, current_ts - last_timestamp);
            }
            Err(e) => {
                eprintln!("增量更新失败: {:?}", e);
            }
        }
        
        // 模拟间隔时间
        std::thread::sleep(std::time::Duration::from_secs(10));
    }
}

这个扩展示例展示了:

  1. 从文件加载初始快照数据
  2. 处理增量更新
  3. 时间戳管理和更新间隔控制
  4. 错误处理逻辑

实际使用时,您需要替换文件加载逻辑为实际的网络请求,并根据您的应用场景调整更新频率和错误处理策略。


1 回复

Rust闪电网络高效同步库lightning-rapid-gossip-sync使用指南

简介

lightning-rapid-gossip-sync 是一个用于闪电网络的高效数据同步库,它能够帮助比特币节点快速同步网络拓扑数据。该库专为Rust语言设计,是Lightning Development Kit (LDK)生态系统的一部分。

主要特点:

  • 高效同步闪电网络的路由信息(gossip data)
  • 减少初始同步时间
  • 降低带宽消耗
  • 与标准LDK gossip同步兼容

安装方法

在Cargo.toml中添加依赖:

[dependencies]
lightning-rapid-gossip-sync = "0.2"

基本使用方法

1. 初始化同步器

use lightning_rapid_gossip_sync::RapidGossipSync;
use lightning::util::ser::ReadableArgs;
use std::sync::Arc;

// 创建RapidGossipSync实例
let rapid_sync = RapidGossipSync::new(
    Arc::clone(&network_graph),  // 共享的网络图
    Arc::clone(&logger)          // 共享的日志器
);

2. 从远程服务器获取并处理gossip数据

use bitcoin::hashes::hex::FromHex;
use lightning::routing::gossip::NetworkGraph;

// 假设我们从服务器获取了压缩的gossip数据
let compressed_data = Vec::<u8>::from_hex("0123456789abcdef...").unwrap();

match rapid_sync.sync_network_graph_with_compressed_data(&compressed_data) {
    Ok(_) => println!("同步成功!"),
    Err(e) => eprintln!("同步失败: {:?}", e),
}

3. 与持续同步结合使用

use lightning::ln::msgs::GossipSync;

// 创建混合同步策略
let gossip_sync = GossipSync::rapid(rapid_sync);

// 然后可以像使用普通gossip同步器一样使用它

高级用法

自定义服务器端点

use std::time::Duration;
use reqwest::Url;

let custom_server = Url::parse("https://my-gossip-server.com/sync").unwrap();

// 设置超时
let client = reqwest::Client::builder()
    .timeout(Duration::from_secs(30))
    .build()
    .unwrap();

// 从自定义服务器获取数据
let response = client.get(custom_server).send().await?;
let compressed_data = response.bytes().await?.to_vec();

处理部分更新

// 获取最新更新而不是完整快照
let last_sync_timestamp = rapid_sync.last_sync_timestamp();

let update_url = format!("https://gossip-server.com/updates?since={}", last_sync_timestamp);
let response = client.get(update_url).send().await?;
let update_data = response.bytes().await?.to_vec();

rapid_sync.update_network_graph_with_compressed_data(&update_data)?;

示例:完整初始化流程

use lightning::routing::gossip::NetworkGraph;
use lightning::util::logger::{Logger, Record};
use lightning::util::ser::Writeable;
use std::sync::Arc;

// 1. 创建网络图和日志器
struct SimpleLogger;
impl Logger for SimpleLogger {
    fn log(&self, record: &Record) {
        println!("{} -- {}: {}", record.level, record.module_path, record.args);
    }
}

let network_graph = Arc::new(NetworkGraph::new(Network::Bitcoin));
let logger = Arc::new(SimpleLogger);

// 2. 创建RapidGossipSync实例
let rapid_sync = RapidGossipSync::new(
    Arc::clone(&network_graph),
    Arc::clone(&logger)
);

// 3. 从默认服务器获取数据
let default_server = "https://rapidsync.lightningdevkit.org/snapshot";
let response = reqwest::blocking::get(default_server)?;
let compressed_data = response::bytes()?.to_vec();

// 4. 同步数据
rapid_sync.sync_network_graph_with_compressed_data(&compressed_data)?;

println!("初始同步完成! 网络图包含 {} 个节点", 
    network_graph.nodes().len());

完整示例Demo

下面是一个完整的示例,展示如何使用lightning-rapid-gossip-sync进行闪电网络数据同步:

use lightning::routing::gossip::NetworkGraph;
use lightning::util::logger::{Logger, Record};
use lightning_rapid_gossip_sync::RapidGossipSync;
use std::sync::Arc;
use reqwest::blocking::get;
use bitcoin::network::constants::Network;

// 自定义简单日志记录器
struct SimpleLogger;
impl Logger for SimpleLogger {
    fn log(&self, record: &Record) {
        println!("[{}] {} - {}", 
            record.level.to_string(), 
            record.module_path, 
            record.args);
    }
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 1. 初始化网络图和日志器
    let network_graph = Arc::new(NetworkGraph::new(Network::Bitcoin));
    let logger = Arc::new(SimpleLogger);

    // 2. 创建RapidGossipSync实例
    let rapid_sync = RapidGossipSync::new(
        Arc::clone(&network_graph),
        Arc::clone(&logger)
    );

    // 3. 从服务器获取压缩的gossip数据
    println!("正在从服务器获取gossip数据...");
    let server_url = "https://rapidsync.lightningdevkit.org/snapshot";
    let response = get(server_url)?;
    let compressed_data = response.bytes()?.to_vec();

    // 4. 同步网络图数据
    println!("正在同步网络图数据...");
    rapid_sync.sync_network_graph_with_compressed_data(&compressed_data)?;

    // 5. 输出同步结果
    println!("\n同步成功完成!");
    println!("当前网络图统计:");
    println!("- 节点数量: {}", network_graph.nodes().len());
    println!("- 通道数量: {}", network_graph.channels().len());

    Ok(())
}

注意事项

  1. 该库主要用于初始同步,后续更新建议使用常规的gossip协议
  2. 同步的数据需要验证签名,确保来自可信源
  3. 默认服务器可能不适合生产环境,建议自建同步服务器
  4. 同步完成后,网络图需要定期更新以保持最新状态

性能建议

  1. 对于移动设备或资源受限环境,此库特别有用
  2. 可以设置定期检查更新(如每小时一次)
  3. 在应用启动时优先使用此库进行快速同步,然后切换到常规gossip协议

通过使用lightning-rapid-gossip-sync,开发者可以显著改善闪电网络应用的启动时间和网络拓扑更新效率。

回到顶部