Skip to content

Commit

Permalink
Migrate nip46 servers
Browse files Browse the repository at this point in the history
  • Loading branch information
mikedilger committed Feb 5, 2024
1 parent 252513a commit 559113c
Show file tree
Hide file tree
Showing 4 changed files with 189 additions and 7 deletions.
58 changes: 58 additions & 0 deletions gossip-lib/src/storage/migrations/m26.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
use crate::error::Error;
use crate::nip46::{Approval, Nip46ClientMetadata, Nip46Server};
use crate::storage::Storage;
use heed::RwTxn;
use nostr_types::{PublicKey, RelayUrl};
use speedy::{Readable, Writable};

#[derive(Debug, Clone, Readable, Writable)]
pub struct Nip46Server1 {
pub peer_pubkey: PublicKey,
pub relays: Vec<RelayUrl>,
pub metadata: Option<Nip46ClientMetadata>,
}

impl Storage {
pub(super) fn m26_trigger(&self) -> Result<(), Error> {
let _ = self.db_nip46servers1()?;
let _ = self.db_nip46servers2()?;
Ok(())
}

pub(super) fn m26_migrate<'a>(
&'a self,
prefix: &str,
txn: &mut RwTxn<'a>,
) -> Result<(), Error> {
// Info message
tracing::info!("{prefix}: migrating nostr connect services...");

// Migrate
self.m26_migrate_nostr_connect_services(txn)?;

Ok(())
}

fn m26_migrate_nostr_connect_services<'a>(&'a self, txn: &mut RwTxn<'a>) -> Result<(), Error> {
let loop_txn = self.env.read_txn()?;
for result in self.db_nip46servers1()?.iter(&loop_txn)? {
let (key, val) = result?;
let server1 = Nip46Server1::read_from_buffer(val)?;
let server2 = Nip46Server {
peer_pubkey: server1.peer_pubkey,
relays: server1.relays,
metadata: server1.metadata,
sign_approval: Approval::None,
encrypt_approval: Approval::None,
decrypt_approval: Approval::None,
};
let bytes = server2.write_to_vec()?;
self.db_nip46servers2()?.put(txn, key, &bytes)?;
}

// clear old database (we don't have an interface to delete it)
self.db_nip46servers1()?.clear(txn)?;

Ok(())
}
}
5 changes: 4 additions & 1 deletion gossip-lib/src/storage/migrations/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ mod m22;
mod m23;
mod m24;
mod m25;
mod m26;
mod m3;
mod m4;
mod m5;
Expand All @@ -31,7 +32,7 @@ use crate::error::{Error, ErrorKind};
use heed::RwTxn;

impl Storage {
const MAX_MIGRATION_LEVEL: u32 = 25;
const MAX_MIGRATION_LEVEL: u32 = 26;

/// Initialize the database from empty
pub(super) fn init_from_empty(&self) -> Result<(), Error> {
Expand Down Expand Up @@ -111,6 +112,7 @@ impl Storage {
23 => self.m23_trigger()?,
24 => self.m24_trigger()?,
25 => self.m25_trigger()?,
26 => self.m26_trigger()?,
_ => panic!("Unreachable migration level"),
}

Expand Down Expand Up @@ -145,6 +147,7 @@ impl Storage {
23 => self.m23_migrate(&prefix, txn)?,
24 => self.m24_migrate(&prefix, txn)?,
25 => self.m25_migrate(&prefix, txn)?,
26 => self.m26_migrate(&prefix, txn)?,
_ => panic!("Unreachable migration level"),
};

Expand Down
13 changes: 7 additions & 6 deletions gossip-lib/src/storage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ mod events2;
mod events3;
mod hashtags1;
mod nip46servers1;
mod nip46servers2;
mod people1;
mod people2;
mod person_lists1;
Expand Down Expand Up @@ -239,7 +240,7 @@ impl Storage {
let _ = self.db_event_seen_on_relay()?;
let _ = self.db_event_viewed()?;
let _ = self.db_hashtags()?;
let _ = self.db_nip46servers1()?;
let _ = self.db_nip46servers()?;
let _ = self.db_people()?;
let _ = self.db_person_relays()?;
let _ = self.db_relationships_by_id()?;
Expand Down Expand Up @@ -310,7 +311,7 @@ impl Storage {

#[inline]
pub(crate) fn db_nip46servers(&self) -> Result<RawDatabase, Error> {
self.db_nip46servers1()
self.db_nip46servers2()
}

#[inline]
Expand Down Expand Up @@ -2598,22 +2599,22 @@ impl Storage {
server: &Nip46Server,
rw_txn: Option<&mut RwTxn<'a>>,
) -> Result<(), Error> {
self.write_nip46server1(server, rw_txn)
self.write_nip46server2(server, rw_txn)
}

pub fn read_nip46server(&self, pubkey: PublicKey) -> Result<Option<Nip46Server>, Error> {
self.read_nip46server1(pubkey)
self.read_nip46server2(pubkey)
}

pub fn read_all_nip46servers(&self) -> Result<Vec<Nip46Server>, Error> {
self.read_all_nip46servers1()
self.read_all_nip46servers2()
}

pub fn delete_nip46server<'a>(
&'a self,
pubkey: PublicKey,
rw_txn: Option<&mut RwTxn<'a>>,
) -> Result<(), Error> {
self.delete_nip46server1(pubkey, rw_txn)
self.delete_nip46server2(pubkey, rw_txn)
}
}
120 changes: 120 additions & 0 deletions gossip-lib/src/storage/nip46servers2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
use crate::error::Error;
use crate::nip46::Nip46Server;
use crate::storage::{RawDatabase, Storage};
use heed::types::UnalignedSlice;
use heed::RwTxn;
use nostr_types::PublicKey;
use speedy::{Readable, Writable};
use std::sync::Mutex;

// PublicKey -> Nip46Server
// key: pubkey.as_bytes()
// val: nip46server.write_to_vec() | Nip46Server::read_from_buffer(val)

static NIP46SERVER2_DB_CREATE_LOCK: Mutex<()> = Mutex::new(());
static mut NIP46SERVER2_DB: Option<RawDatabase> = None;

impl Storage {
pub(super) fn db_nip46servers2(&self) -> Result<RawDatabase, Error> {
unsafe {
if let Some(db) = NIP46SERVER2_DB {
Ok(db)
} else {
// Lock. This drops when anything returns.
let _lock = NIP46SERVER2_DB_CREATE_LOCK.lock();

// In case of a race, check again
if let Some(db) = NIP46SERVER2_DB {
return Ok(db);
}

// Create it. We know that nobody else is doing this and that
// it cannot happen twice.
let mut txn = self.env.write_txn()?;
let db = self
.env
.database_options()
.types::<UnalignedSlice<u8>, UnalignedSlice<u8>>()
// no .flags needed
.name("nip46server2")
.create(&mut txn)?;
txn.commit()?;
NIP46SERVER2_DB = Some(db);
Ok(db)
}
}
}

#[allow(dead_code)]
pub(crate) fn write_nip46server2<'a>(
&'a self,
server: &Nip46Server,
rw_txn: Option<&mut RwTxn<'a>>,
) -> Result<(), Error> {
let key = server.peer_pubkey.as_bytes();
let bytes = server.write_to_vec()?;

let f = |txn: &mut RwTxn<'a>| -> Result<(), Error> {
self.db_nip46servers2()?.put(txn, key, &bytes)?;
Ok(())
};

match rw_txn {
Some(txn) => f(txn)?,
None => {
let mut txn = self.env.write_txn()?;
f(&mut txn)?;
txn.commit()?;
}
};

Ok(())
}

pub(crate) fn read_nip46server2(
&self,
pubkey: PublicKey,
) -> Result<Option<Nip46Server>, Error> {
let key = pubkey.as_bytes();
let txn = self.env.read_txn()?;
Ok(match self.db_nip46servers2()?.get(&txn, key)? {
Some(bytes) => Some(Nip46Server::read_from_buffer(bytes)?),
None => None,
})
}

pub(crate) fn read_all_nip46servers2(&self) -> Result<Vec<Nip46Server>, Error> {
let txn = self.env.read_txn()?;
let mut output: Vec<Nip46Server> = Vec::new();
for result in self.db_nip46servers2()?.iter(&txn)? {
let (_key, val) = result?;
let server = Nip46Server::read_from_buffer(val)?;
output.push(server);
}
Ok(output)
}

pub(crate) fn delete_nip46server2<'a>(
&'a self,
pubkey: PublicKey,
rw_txn: Option<&mut RwTxn<'a>>,
) -> Result<(), Error> {
let key = pubkey.as_bytes();

let f = |txn: &mut RwTxn<'a>| -> Result<(), Error> {
let _ = self.db_nip46servers2()?.delete(txn, key);
Ok(())
};

match rw_txn {
Some(txn) => f(txn)?,
None => {
let mut txn = self.env.write_txn()?;
f(&mut txn)?;
txn.commit()?;
}
};

Ok(())
}
}

0 comments on commit 559113c

Please sign in to comment.