返回

有了 PeerStore, Rust 开发人员现在可以简化 Rust 实现中的地址搜索

闲谈

在 Rust 实现的 libp2p 中,协议想要获取特定节点或对等方的地址时,必须实现 NetworkBehaviour 的 addresses_of_peer 方法。与之不同的是,Go 实现的 libp2p 使用 peerstore 来存储节点或对等方的 ID 与其相应地址之间的关系,因此,我们可以参考它的方法来大幅简化 Rust 中协议的实现。

Rust 中地址查询的常规实现方式

Rust 实现的 libp2p 中,想要获取特定对等方的地址时,需要编写如下代码:

    /// 返回与 `peer_id` 关联的地址
    fn addresses_of_peer(&mut self, peer_id: &PeerId) -> Async<Vec<Multiaddr>> {
        Box::pin(async move {
            let dhts = self.connection_manager.peer_store.peer_store.dht_list().await;
            let mut addresses = vec![];
            for dht in dhts {
                if let Some(result) = dht.get_value(peer_id, ProtocolInfo::new("/ipfs/kad/1.0.0".into())).await {
                    match result {
                        DhtValue::Record(rec) => {
                            for address in rec.value.iter().filter_map(|v| {
                                Multiaddr::try_from(v).ok()
                            }) {
                                addresses.push(address);
                            }
                        }
                        _ => {}
                    }
                }
            }
            addresses
        })
    }

可以看出,这段代码需要与多个 DHT 交互,并且 DHT 中存储的地址不一定是可用的,这就导致了查询结果不那么可靠。更重要的是,这种方法要求协议实现者自行实现地址搜索逻辑,增加了实现难度。

使用 PeerStore 简化 Rust 中地址搜索

为了解决这些问题,Rust 中的 libp2p 可以像 Go 实现那样使用 PeerStore。PeerStore 是一个哈希表,其中存储了对等方的 ID 与其相应地址之间的映射关系。使用 PeerStore,我们可以轻松地获取特定对等方的地址,而无需与 DHT 交互或自行实现地址搜索逻辑。

要使用 PeerStore,需要首先创建并启动一个 PeerStore 实例:

let peer_store = PeerStore::new();
let mut store_handle = peer_store.handle();
task::spawn(async move {
    store_handle.start().await.unwrap();
});

然后,就可以使用 PeerStore 来获取对等方的地址了。代码如下:

fn addresses_of_peer(&mut self, peer_id: &PeerId) -> Async<Vec<Multiaddr>> {
    Box::pin(async move {
        let addresses = self.peer_store.peer_store.addresses_of_peer(peer_id);
        addresses
            .map(|addresses| addresses.iter().map(|address| address.to_string()).collect())
            .await
    })
}

与之前的实现相比,这段代码更加简单,并且查询结果更加可靠。

总结

Rust 中的 PeerStore 可以大幅简化 Rust 实现中协议的实现。使用 PeerStore,开发人员可以轻松地获取特定对等方的地址,而无需与 DHT 交互或自行实现地址搜索逻辑。这不仅简化了协议的实现,而且还提高了查询结果的可靠性。

进一步阅读