diff options
| author | murilo ijanc | 2026-03-24 15:04:03 -0300 |
|---|---|---|
| committer | murilo ijanc | 2026-03-24 15:04:03 -0300 |
| commit | 9821aabf0b50d2487b07502d3d2cd89e7d62bdbe (patch) | |
| tree | 53da095ff90cc755bac3d4bf699172b5e8cd07d6 /src/persist.rs | |
| download | tesseras-dht-9821aabf0b50d2487b07502d3d2cd89e7d62bdbe.tar.gz | |
Initial commitv0.1.0
NAT-aware Kademlia DHT library for peer-to-peer networks.
Features:
- Distributed key-value storage (iterative FIND_NODE, FIND_VALUE, STORE)
- NAT traversal via DTUN hole-punching and proxy relay
- Reliable Datagram Protocol (RDP) with 7-state connection machine
- Datagram transport with automatic fragmentation/reassembly
- Ed25519 packet authentication
- 256-bit node IDs (Ed25519 public keys)
- Rate limiting, ban list, and eclipse attack mitigation
- Persistence and metrics
- OpenBSD and Linux support
Diffstat (limited to 'src/persist.rs')
| -rw-r--r-- | src/persist.rs | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/src/persist.rs b/src/persist.rs new file mode 100644 index 0000000..8e733b0 --- /dev/null +++ b/src/persist.rs @@ -0,0 +1,84 @@ +//! Persistence traits for data and routing table. +//! +//! The library defines the traits; applications +//! implement backends (SQLite, file, etc). + +use crate::error::Error; +use crate::id::NodeId; +use std::net::SocketAddr; + +/// Stored value record for persistence. +#[derive(Debug, Clone)] +pub struct StoredRecord { + pub key: Vec<u8>, + pub value: Vec<u8>, + pub target_id: NodeId, + pub source: NodeId, + pub ttl: u16, + pub is_unique: bool, +} + +/// Contact record for routing table persistence. +#[derive(Debug, Clone)] +pub struct ContactRecord { + pub id: NodeId, + pub addr: SocketAddr, +} + +/// Trait for persisting DHT stored values. +/// +/// Implement this to survive restarts. The library +/// calls `save` periodically and `load` on startup. +pub trait DataPersistence { + /// Save all stored values. + fn save(&self, records: &[StoredRecord]) -> Result<(), Error>; + + /// Load previously saved values. + fn load(&self) -> Result<Vec<StoredRecord>, Error>; +} + +/// Trait for persisting the routing table. +/// +/// Implement this for fast re-bootstrap after restart. +pub trait RoutingPersistence { + /// Save known contacts. + fn save_contacts(&self, contacts: &[ContactRecord]) -> Result<(), Error>; + + /// Load previously saved contacts. + fn load_contacts(&self) -> Result<Vec<ContactRecord>, Error>; +} + +/// No-op persistence (default — no persistence). +pub struct NoPersistence; + +impl DataPersistence for NoPersistence { + fn save(&self, _records: &[StoredRecord]) -> Result<(), Error> { + Ok(()) + } + fn load(&self) -> Result<Vec<StoredRecord>, Error> { + Ok(Vec::new()) + } +} + +impl RoutingPersistence for NoPersistence { + fn save_contacts(&self, _contacts: &[ContactRecord]) -> Result<(), Error> { + Ok(()) + } + fn load_contacts(&self) -> Result<Vec<ContactRecord>, Error> { + Ok(Vec::new()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn no_persistence_save_load() { + let p = NoPersistence; + assert!(p.save(&[]).is_ok()); + assert!(p.load().unwrap().is_empty()); + assert!(p.save_contacts(&[]).is_ok()); + assert!(p.load_contacts().unwrap().is_empty()); + } +} |