4 个稳定版本

使用旧 Rust 2015

1.0.3 2016 年 9 月 27 日
1.0.2 2016 年 9 月 10 日

#7 in #kademlia

MIT 许可证

130KB
2.5K SLoC

Subotai

Subotai 是一个基于 Kademlia 的分布式哈希表。它设计得易于使用、安全且快速。以下是使其与其他 DHT 区别的一些想法

  • 外部同步,内部并发:所有公共方法都是阻塞的,并返回一个合理的或明确的超时结果。然而,内部 subotai 完全并发,并行操作通常会相互帮助完成。

  • 优先引入节点,然后解决冲突:Subotai 与原始 Kademlia 实现不同之处在于,它给新接触到的临时节点以全桶的优先权。这使得网络更加动态和能够快速适应,同时仍提供防御性状态来保护基本 DDoS 攻击。

  • 灵活的存储:键空间中的每个键都可以存储任意数量的不同条目,每个条目具有独立的过期时间。

  • 急迫:Subotai 是“急迫”的,这意味着它将尝试从不响应的节点那里永不等待响应。在可能的情况下,查询会并行发送,并在一小部分节点响应时继续处理。

Subotai 支持自动密钥重新发布,提供良好的保证,确保条目将保留在网络中,直到配置的过期日期。手动将条目存储在网络中可以刷新过期日期。

Subotai 还支持缓存,以平衡围绕特定键的密集流量。

文档

如何使用

假设我们在一台机器上运行以下代码

fn main() {
   let node = node::Node::new().unwrap();

   // We join the network through the address of any live node.
   let seed = net::SocketAddr::from_str("192.168.1.100:50000").unwrap();
   node.bootstrap(&seed);

   // We store a key->data pair.
   let my_key = hash::SubotaiHash::sha1("example_key");
   let my_data = vec![0u8,1,2,3,4,5];
   node.store(my_key, node::StorageEntry::Blob(my_data));
}

只要网络中有足够数量的节点(一个可配置的数量,被认为是网络活跃的足够数量),我们就成功地将数据存储在表中。

现在,在非常、非常遥远的另一台机器上...

fn main() {
   let node = node::Node::new().unwrap();

   // We join the same network (can be on a different node).
   let seed = net::SocketAddr::from_str("192.168.1.230:40000").unwrap();
   node.bootstrap(&seed);

   // We retrieve all entries for the same key.
   let my_key = hash::SubotaiHash::sha1("example_key");
   let retrieved_entries = node.retrieve(&my_key).unwrap();

   // We get what we stored. In O(log n) number of steps, of course!
   assert_eq!(retrieved_entries.len(), 1);
   let expected_data = vec![0u8,1,2,3,4,5];
   assert_eq!(*retrieved_entries.first().unwrap(), node::StorageEntry::Blob(expected_data));
}

项目状态

Subotai 功能完整,但处于测试的早期阶段。我专注于使 API 尽可能稳定(部分是通过通过工厂处理所有配置,以防止新的配置选项成为破坏性更改),并为构建在它之上的实际应用提供功能基线。

尽管每个功能都经过了单元测试,但网络尚未在实际条件下进行测试。我真的非常感谢任何实验!只是请确保不要将其用于任何关键任务:)。

关于测试的说明

苏博泰的单元测试套件有些繁琐,因为库广泛使用超时来进行决策。这意味着,除非你正在运行一台非常强大的机器,否则你应该使用 cargo test 命令与 RUST_TEST_THREADS=1 一起运行。否则,过多的并行测试可能会导致到处超时,使得网络错误地将节点识别为已死亡。

依赖项

约4MB
约76K SLoC