Skip to content

Commit 9747a15

Browse files
committed
sdk: init reconcilie method for Relay
1 parent decfbcc commit 9747a15

File tree

4 files changed

+124
-2
lines changed

4 files changed

+124
-2
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright (c) 2022-2023 Yuki Kishimoto
2+
// Distributed under the MIT software license
3+
4+
use nostr_sdk::prelude::*;
5+
6+
const BECH32_SK: &str = "nsec1ufnus6pju578ste3v90xd5m2decpuzpql2295m3sknqcjzyys9ls0qlc85";
7+
8+
#[tokio::main]
9+
async fn main() -> Result<()> {
10+
tracing_subscriber::fmt::init();
11+
12+
let secret_key = SecretKey::from_bech32(BECH32_SK)?;
13+
let my_keys = Keys::new(secret_key);
14+
15+
let client = Client::new(&my_keys);
16+
client.add_relay("wss://relay.damus.io", None).await?;
17+
18+
client.connect().await;
19+
20+
let filter = Filter::new()
21+
.author(my_keys.public_key().to_string())
22+
.limit(10);
23+
let relay = client.relay("wss://relay.damus.io").await?;
24+
relay
25+
.reconcilie(filter, vec![(EventId::all_zeros(), Timestamp::now())])
26+
.await?;
27+
28+
Ok(())
29+
}

crates/nostr-sdk/src/relay/mod.rs

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ use std::time::Instant;
1919
use async_utility::futures_util::stream::AbortHandle;
2020
use async_utility::{futures_util, thread, time};
2121
use nostr::message::MessageHandleError;
22+
use nostr::negentropy::hex;
23+
use nostr::negentropy::{self, Bytes, Negentropy};
2224
#[cfg(feature = "nip11")]
2325
use nostr::nips::nip11::RelayInformationDocument;
2426
use nostr::{ClientMessage, Event, EventId, Filter, RelayMessage, SubscriptionId, Timestamp, Url};
@@ -41,6 +43,12 @@ type Message = (RelayEvent, Option<oneshot::Sender<bool>>);
4143
/// [`Relay`] error
4244
#[derive(Debug, Error)]
4345
pub enum Error {
46+
/// Negentropy error
47+
#[error(transparent)]
48+
Negentropy(#[from] negentropy::Error),
49+
/// Hex error
50+
#[error(transparent)]
51+
Hex(#[from] hex::Error),
4452
/// Channel timeout
4553
#[error("channel timeout")]
4654
ChannelTimeout,
@@ -1546,4 +1554,89 @@ impl Relay {
15461554
}
15471555
});
15481556
}
1557+
1558+
/// Negentropy reconciliation
1559+
pub async fn reconcilie(
1560+
&self,
1561+
filter: Filter,
1562+
my_items: Vec<(EventId, Timestamp)>,
1563+
) -> Result<(), Error> {
1564+
if !self.opts.read() {
1565+
return Err(Error::ReadDisabled);
1566+
}
1567+
1568+
let id_size: usize = 16;
1569+
1570+
let mut negentropy = Negentropy::new(id_size, Some(5_000))?;
1571+
1572+
for (id, timestamp) in my_items.into_iter() {
1573+
let cutted_id: &[u8] = &id.as_bytes()[..id_size];
1574+
let cutted_id = Bytes::from_slice(cutted_id);
1575+
negentropy.add_item(timestamp.as_u64(), cutted_id)?;
1576+
}
1577+
1578+
negentropy.seal()?;
1579+
1580+
let id = SubscriptionId::generate();
1581+
let open_msg = ClientMessage::neg_open(&mut negentropy, &id, filter)?;
1582+
1583+
self.send_msg(open_msg, Some(Duration::from_secs(10)))
1584+
.await?;
1585+
1586+
let mut notifications = self.notification_sender.subscribe();
1587+
while let Ok(notification) = notifications.recv().await {
1588+
if let RelayPoolNotification::Message(url, msg) = notification {
1589+
if url == self.url {
1590+
match msg {
1591+
RelayMessage::NegMsg {
1592+
subscription_id,
1593+
message,
1594+
} => {
1595+
if subscription_id == id {
1596+
let query: Bytes = Bytes::from_hex(message)?;
1597+
let mut need_ids: Vec<Bytes> = Vec::new();
1598+
let msg: Option<Bytes> = negentropy.reconcile_with_ids(
1599+
&query,
1600+
&mut Vec::new(),
1601+
&mut need_ids,
1602+
)?;
1603+
1604+
// TODO: request ids to relay
1605+
println!("IDs: {need_ids:?}");
1606+
1607+
match msg {
1608+
Some(query) => {
1609+
self.send_msg(
1610+
ClientMessage::NegMsg {
1611+
subscription_id: id.clone(),
1612+
message: query.to_hex(),
1613+
},
1614+
None,
1615+
)
1616+
.await?;
1617+
}
1618+
None => {
1619+
tracing::info!("Reconciliation terminated");
1620+
break;
1621+
}
1622+
}
1623+
}
1624+
}
1625+
RelayMessage::NegErr {
1626+
subscription_id,
1627+
code,
1628+
} => {
1629+
if subscription_id == id {
1630+
tracing::error!("Negentropy syncing error: {code}");
1631+
break;
1632+
}
1633+
}
1634+
_ => (),
1635+
}
1636+
}
1637+
}
1638+
}
1639+
1640+
Ok(())
1641+
}
15491642
}

crates/nostr/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ bip39 = { version = "2.0", default-features = false, optional = true }
5656
bitcoin = { version = "0.30", default-features = false, features = ["rand", "serde"] }
5757
cbc = { version = "0.1", optional = true }
5858
chacha20 = { version = "0.9", optional = true }
59-
negentropy = { git = "https://github.com/yukibtc/rust-negentropy", rev = "62a65db938c7088d521980d3fc1e1593713a899d", default-features = false }
59+
negentropy = { git = "https://github.com/yukibtc/rust-negentropy", rev = "547592168356f423dd10773384b798e7c7139893", default-features = false }
6060
nostr-ots = { version = "0.2", optional = true }
6161
once_cell = { workspace = true, optional = true }
6262
reqwest = { version = "0.11", default-features = false, features = ["json", "rustls-tls-webpki-roots", "socks"], optional = true }

0 commit comments

Comments
 (0)