serialization and db patches

This commit is contained in:
kn0sys 2024-09-06 05:54:26 -04:00
parent eb5c0b370d
commit 33a76fcd63
No known key found for this signature in database
GPG key ID: 3BDB674C95F103FA
8 changed files with 222 additions and 209 deletions

View file

@ -47,8 +47,8 @@ pub fn create(address: &String) -> Result<Authorization, MdbError> {
token, token,
xmr_address: String::from(address), xmr_address: String::from(address),
}; };
let env = utils::get_release_env();
let s = db::DatabaseEnvironment::open(&env.value())?; let s = db::DatabaseEnvironment::open()?;
debug!("insert auth: {:?}", &new_auth); debug!("insert auth: {:?}", &new_auth);
let k = &new_auth.aid.as_bytes(); let k = &new_auth.aid.as_bytes();
let v = bincode::serialize(&new_auth).unwrap_or_default(); let v = bincode::serialize(&new_auth).unwrap_or_default();
@ -59,8 +59,8 @@ pub fn create(address: &String) -> Result<Authorization, MdbError> {
/// Authorization lookup for recurring requests /// Authorization lookup for recurring requests
pub fn find(aid: &String) -> Result<Authorization, MdbError> { pub fn find(aid: &String) -> Result<Authorization, MdbError> {
info!("searching for auth: {}", aid); info!("searching for auth: {}", aid);
let env = utils::get_release_env();
let s = db::DatabaseEnvironment::open(&env.value())?; let s = db::DatabaseEnvironment::open()?;
let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &aid.as_bytes().to_vec())?; let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &aid.as_bytes().to_vec())?;
if r.is_empty() { if r.is_empty() {
return Err(MdbError::NotFound); return Err(MdbError::NotFound);
@ -81,12 +81,12 @@ fn update_expiration(f_auth: &Authorization, address: &String) -> Result<Authori
data, data,
create_token(String::from(address), time), create_token(String::from(address), time),
); );
let env = utils::get_release_env();
let s = db::DatabaseEnvironment::open(&env.value())?; let s = db::DatabaseEnvironment::open()?;
db::DatabaseEnvironment::delete(&s.env, &s.handle?, &u_auth.aid.as_bytes().to_vec()); db::DatabaseEnvironment::delete(&s.env, &s.handle?, &u_auth.aid.as_bytes().to_vec());
let k = u_auth.aid.as_bytes(); let k = u_auth.aid.as_bytes();
let v = bincode::serialize(&u_auth).unwrap_or_default(); let v = bincode::serialize(&u_auth).unwrap_or_default();
let s = db::DatabaseEnvironment::open(&env.value())?; let s = db::DatabaseEnvironment::open()?;
db::write_chunks(&s.env, &s.handle?, k, &v); db::write_chunks(&s.env, &s.handle?, k, &v);
Ok(u_auth) Ok(u_auth)
} }
@ -124,11 +124,11 @@ pub async fn verify_login(aid: String, uid: String, signature: String) -> Result
let u: User = user::create(&address)?; let u: User = user::create(&address)?;
// update auth with uid // update auth with uid
let u_auth = Authorization::update_uid(f_auth, String::from(&u.uid)); let u_auth = Authorization::update_uid(f_auth, String::from(&u.uid));
let env = utils::get_release_env();
let s = db::DatabaseEnvironment::open(&env.value())?; let s = db::DatabaseEnvironment::open()?;
db::DatabaseEnvironment::delete(&s.env, &s.handle?, &u_auth.aid.as_bytes()); db::DatabaseEnvironment::delete(&s.env, &s.handle?, &u_auth.aid.as_bytes());
let v = bincode::serialize(&u_auth).unwrap_or_default(); let v = bincode::serialize(&u_auth).unwrap_or_default();
let s = db::DatabaseEnvironment::open(&env.value())?; let s = db::DatabaseEnvironment::open()?;
db::write_chunks(&s.env, &s.handle?, u_auth.aid.as_bytes(), &v); db::write_chunks(&s.env, &s.handle?, u_auth.aid.as_bytes(), &v);
monero::close_wallet(&wallet_name, &wallet_password).await; monero::close_wallet(&wallet_name, &wallet_password).await;
Ok(u_auth) Ok(u_auth)
@ -185,7 +185,7 @@ fn get_auth_expiration() -> i64 {
} }
fn create_token(address: String, created: i64) -> String { fn create_token(address: String, created: i64) -> String {
let jwt_secret_key = utils::get_jwt_secret_key(); let jwt_secret_key = utils::get_jwt_secret_key().unwrap_or_default();
let key: Hmac<Sha384> = Hmac::new_from_slice(jwt_secret_key.as_bytes()).expect("hash"); let key: Hmac<Sha384> = Hmac::new_from_slice(jwt_secret_key.as_bytes()).expect("hash");
let header = Header { let header = Header {
algorithm: AlgorithmType::Hs384, algorithm: AlgorithmType::Hs384,
@ -239,7 +239,7 @@ impl<'r> FromRequest<'r> for BearerToken {
match token { match token {
Some(token) => { Some(token) => {
// check validity // check validity
let jwt_secret_key = utils::get_jwt_secret_key(); let jwt_secret_key = utils::get_jwt_secret_key().unwrap_or_default();
let key: Hmac<Sha384> = Hmac::new_from_slice(jwt_secret_key.as_bytes()).expect(""); let key: Hmac<Sha384> = Hmac::new_from_slice(jwt_secret_key.as_bytes()).expect("");
let jwt: Result< let jwt: Result<
Token<jwt::Header, BTreeMap<std::string::String, std::string::String>, _>, Token<jwt::Header, BTreeMap<std::string::String, std::string::String>, _>,
@ -282,22 +282,21 @@ impl<'r> FromRequest<'r> for BearerToken {
mod tests { mod tests {
use super::*; use super::*;
async fn find_test_auth(k: &String) -> Result<Authorization, MdbError> { fn find_test_auth(k: &String) -> Result<Authorization, MdbError> {
tokio::time::sleep(std::time::Duration::from_secs(1)).await; let s: db::Interface = db::DatabaseEnvironment::open()?;
let s: db::Interface = db::DatabaseEnvironment::async_open("test").await; let v = db::DatabaseEnvironment::read(&s.env, &s.handle, &k.as_bytes().to_vec())?;
let v = db::DatabaseEnvironment::read(&s.env, &s.handle, k).await; let result: Authorization = bincode::deserialize(&v[..]).unwrap_or_default();
Authorization::from_db(String::from(k), v) Ok(result)
} }
async fn cleanup(k: &String) -> Result<(), MdbError>{ fn cleanup(k: &String) -> Result<(), MdbError>{
tokio::time::sleep(std::time::Duration::from_secs(1)).await; let s = db::DatabaseEnvironment::open()?;
let s = db::DatabaseEnvironment::open("test").await?; db::DatabaseEnvironment::delete(&s.env, &s.handle?, k.as_bytes())?;
db::DatabaseEnvironment::delete(&s.env, &s.handle?, k).await; Ok(())
} }
#[test] #[test]
fn create_test() { fn create_test() {
// run and async cleanup so the test doesn't fail when deleting test data
use tokio::runtime::Runtime; use tokio::runtime::Runtime;
let rt = Runtime::new().expect("Unable to create Runtime for test"); let rt = Runtime::new().expect("Unable to create Runtime for test");
let _enter = rt.enter(); let _enter = rt.enter();
@ -306,49 +305,33 @@ mod tests {
); );
let test_auth = create(&address); let test_auth = create(&address);
assert_eq!(test_auth.xmr_address, address); assert_eq!(test_auth.xmr_address, address);
tokio::spawn(async move { cleanup(&test_auth.aid);
cleanup(&test_auth.aid).await;
});
Runtime::shutdown_background(rt);
} }
#[test] #[test]
fn find_test() { fn find_test() -> Result<(), MdbError> {
// run and async cleanup so the test doesn't fail when deleting test data
use tokio::runtime::Runtime;
let rt = Runtime::new().expect("Unable to create Runtime for test");
let _enter = rt.enter();
let address: String = String::from( let address: String = String::from(
"73a4nWuvkYoYoksGurDjKZQcZkmaxLaKbbeiKzHnMmqKivrCzq5Q2JtJG1UZNZFqLPbQ3MiXCk2Q5bdwdUNSr7X9QrPubkn" "73a4nWuvkYoYoksGurDjKZQcZkmaxLaKbbeiKzHnMmqKivrCzq5Q2JtJG1UZNZFqLPbQ3MiXCk2Q5bdwdUNSr7X9QrPubkn"
); );
let test_auth = create(&address); let test_auth = create(&address);
let aid = String::from(&test_auth.aid); let aid = String::from(&test_auth.aid);
tokio::spawn(async move { let f_auth: Authorization = find_test_auth(&aid);
let f_auth: Authorization = find_test_auth(&aid).await; assert_ne!(f_auth.xmr_address, address);
assert_ne!(f_auth.xmr_address, address); cleanup(&test_auth.aid);
cleanup(&test_auth.aid).await; Ok(())
});
Runtime::shutdown_background(rt);
} }
#[test] #[test]
fn update_expiration_test() { fn update_expiration_test() {
// run and async cleanup so the test doesn't fail when deleting test data
use tokio::runtime::Runtime;
let rt = Runtime::new().expect("Unable to create Runtime for test");
let _enter = rt.enter();
let address: String = String::from( let address: String = String::from(
"73a4nWuvkYoYoksGurDjKZQcZkmaxLaKbbeiKzHnMmqKivrCzq5Q2JtJG1UZNZFqLPbQ3MiXCk2Q5bdwdUNSr7X9QrPubkn" "73a4nWuvkYoYoksGurDjKZQcZkmaxLaKbbeiKzHnMmqKivrCzq5Q2JtJG1UZNZFqLPbQ3MiXCk2Q5bdwdUNSr7X9QrPubkn"
); );
let test_auth = create(&address); let test_auth = create(&address);
let aid = String::from(&test_auth.aid); let aid = String::from(&test_auth.aid);
tokio::spawn(async move { let f_auth = find_test_auth(&aid);
let f_auth = find_test_auth(&aid).await; let u_auth = update_expiration(&f_auth, &address);
let u_auth = update_expiration(&f_auth, &address); assert!(f_auth.created < u_auth.created);
assert!(f_auth.created < u_auth.created); cleanup(&test_auth.aid);
cleanup(&test_auth.aid).await;
});
Runtime::shutdown_background(rt);
} }
#[test] #[test]

View file

@ -39,15 +39,15 @@ pub async fn create(c: &Json<Contact>) -> Result<Contact, MdbError> {
return Ok(Default::default()); return Ok(Default::default());
} }
debug!("insert contact: {:?}", &new_contact); debug!("insert contact: {:?}", &new_contact);
let env = utils::get_release_env();
let s = db::DatabaseEnvironment::open(&env.value())?; let s = db::DatabaseEnvironment::open()?;
let k = &new_contact.cid; let k = &new_contact.cid;
let v = bincode::serialize(&new_contact).unwrap_or_default(); let v = bincode::serialize(&new_contact).unwrap_or_default();
db::write_chunks(&s.env, &s.handle?, k.as_bytes(), &v); db::write_chunks(&s.env, &s.handle?, k.as_bytes(), &v);
// in order to retrieve all contact, write keys to with cl // in order to retrieve all contact, write keys to with cl
let list_key = crate::CONTACT_LIST_DB_KEY; let list_key = crate::CONTACT_LIST_DB_KEY;
let str_lk = String::from(list_key); let str_lk = String::from(list_key);
let s = db::DatabaseEnvironment::open(&env.value())?; let s = db::DatabaseEnvironment::open()?;
let lk_bytes = str_lk.as_bytes(); let lk_bytes = str_lk.as_bytes();
let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &lk_bytes.to_vec())?; let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &lk_bytes.to_vec())?;
if r.is_empty() { if r.is_empty() {
@ -59,15 +59,15 @@ pub async fn create(c: &Json<Contact>) -> Result<Contact, MdbError> {
"writing contact index {} for key {}", "writing contact index {} for key {}",
contact_list, list_key contact_list, list_key
); );
let s = db::DatabaseEnvironment::open(&env.value())?; let s = db::DatabaseEnvironment::open()?;
db::write_chunks(&s.env, &s.handle?, list_key.as_bytes(), &contact_list.as_bytes()); db::write_chunks(&s.env, &s.handle?, list_key.as_bytes(), &contact_list.as_bytes());
Ok(new_contact) Ok(new_contact)
} }
/// Contact lookup /// Contact lookup
pub fn find(cid: &String) -> Result<Contact, MdbError> { pub fn find(cid: &String) -> Result<Contact, MdbError> {
let env = utils::get_release_env();
let s = db::DatabaseEnvironment::open(&env.value())?; let s = db::DatabaseEnvironment::open()?;
let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &cid.as_bytes().to_vec())?; let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &cid.as_bytes().to_vec())?;
if r.is_empty() { if r.is_empty() {
error!("contact not found"); error!("contact not found");
@ -90,14 +90,14 @@ pub fn find_by_i2p_address(i2p_address: &String) -> Result<Contact , MdbError> {
/// Contact deletion /// Contact deletion
pub fn delete(cid: &String) -> Result<(), MdbError> { pub fn delete(cid: &String) -> Result<(), MdbError> {
let env = utils::get_release_env();
let s = db::DatabaseEnvironment::open(&env.value())?; let s = db::DatabaseEnvironment::open()?;
let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &cid.as_bytes().to_vec())?; let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &cid.as_bytes().to_vec())?;
if r.is_empty() { if r.is_empty() {
error!("contact not found"); error!("contact not found");
return Err(MdbError::NotFound); return Err(MdbError::NotFound);
} }
let s = db::DatabaseEnvironment::open(&env.value())?; let s = db::DatabaseEnvironment::open()?;
db::DatabaseEnvironment::delete(&s.env, &s.handle?, cid.as_bytes()); db::DatabaseEnvironment::delete(&s.env, &s.handle?, cid.as_bytes());
Ok(()) Ok(())
} }
@ -105,8 +105,8 @@ pub fn delete(cid: &String) -> Result<(), MdbError> {
/// All contact lookup /// All contact lookup
pub fn find_all() -> Result<Vec<Contact>, MdbError> { pub fn find_all() -> Result<Vec<Contact>, MdbError> {
info!("looking up all contacts"); info!("looking up all contacts");
let env = utils::get_release_env();
let s = db::DatabaseEnvironment::open(&env.value())?; let s = db::DatabaseEnvironment::open()?;
let list_key = crate::CONTACT_LIST_DB_KEY; let list_key = crate::CONTACT_LIST_DB_KEY;
let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &list_key.as_bytes().to_vec())?; let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &list_key.as_bytes().to_vec())?;
if r.is_empty() { if r.is_empty() {
@ -143,8 +143,8 @@ async fn validate_contact(j: &Json<Contact>) -> bool {
/// Send our information /// Send our information
pub async fn share() -> Result<Contact, MdbError> { pub async fn share() -> Result<Contact, MdbError> {
let env = utils::get_release_env();
let s = db::DatabaseEnvironment::open(&env.value())?; let s = db::DatabaseEnvironment::open()?;
let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &NEVEKO_VENDOR_ENABLED.as_bytes().to_vec())?; let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &NEVEKO_VENDOR_ENABLED.as_bytes().to_vec())?;
let str_r: String = bincode::deserialize(&r[..]).unwrap_or_default(); let str_r: String = bincode::deserialize(&r[..]).unwrap_or_default();
let is_vendor = str_r == NEVEKO_VENDOR_MODE_ON; let is_vendor = str_r == NEVEKO_VENDOR_MODE_ON;
@ -154,7 +154,7 @@ pub async fn share() -> Result<Contact, MdbError> {
monero::open_wallet(&wallet_name, &wallet_password).await; monero::open_wallet(&wallet_name, &wallet_password).await;
let m_address: reqres::XmrRpcAddressResponse = monero::get_address().await; let m_address: reqres::XmrRpcAddressResponse = monero::get_address().await;
monero::close_wallet(&wallet_name, &wallet_password).await; monero::close_wallet(&wallet_name, &wallet_password).await;
let nmpk = utils::get_nmpk(); let nmpk = utils::get_nmpk()?;
let i2p_address = i2p::get_destination(None); let i2p_address = i2p::get_destination(None);
let xmr_address = m_address.result.address; let xmr_address = m_address.result.address;
Ok(Contact { Ok(Contact {
@ -233,8 +233,8 @@ mod tests {
use super::*; use super::*;
fn cleanup(k: &String) { fn cleanup(k: &String) {
let env = utils::get_release_env();
let s = db::DatabaseEnvironment::open(&env.value()); let s = db::DatabaseEnvironment::open();
db::DatabaseEnvironment::delete(&s.env, &s.handle, k); db::DatabaseEnvironment::delete(&s.env, &s.handle, k);
} }
@ -276,12 +276,12 @@ mod tests {
..Default::default() ..Default::default()
}; };
tokio::spawn(async move { tokio::spawn(async move {
let s = db::DatabaseEnvironment::async_open().await; let s = db::DatabaseEnvironment::open().unwrap();
db::DatabaseEnvironment::async_write(&s.env, &s.handle, k, &Contact::to_db(&expected_contact)) let v = bincode::serialize(&expected_contact).unwrap_or_default();
.await; db::write_chunks(&s.env, &s.handle, k.as_bytes(), &v);
let actual_contact: Contact = find(&String::from(k)); let actual_contact: Contact = find(&String::from(k));
assert_eq!(expected_contact.xmr_address, actual_contact.xmr_address); assert_eq!(expected_contact.xmr_address, actual_contact.xmr_address);
cleanup(&String::from(k)).await; cleanup(&String::from(k));
}); });
Runtime::shutdown_background(rt); Runtime::shutdown_background(rt);
} }

View file

@ -8,6 +8,8 @@ use lmdb::*;
use log::{error, info}; use log::{error, info};
use sysinfo::System; use sysinfo::System;
use crate::utils;
/// Ratio of map size to available memory is 20 percent /// Ratio of map size to available memory is 20 percent
const MAP_SIZE_MEMORY_RATIO: f32 = 0.2; const MAP_SIZE_MEMORY_RATIO: f32 = 0.2;
/// Ratio of chunk size to available memory is 0.2 percent /// Ratio of chunk size to available memory is 0.2 percent
@ -15,7 +17,7 @@ const CHUNK_SIZE_MEMORY_RATIO: f32 = MAP_SIZE_MEMORY_RATIO * 0.01;
/// The database environment for handling primary database operations. /// The database environment for handling primary database operations.
/// ///
/// By default the database will be written to /home/user/.valentinus/{ENV}/lmdb /// By default the database will be written to /home/user/.neveko/{ENV}/lmdb
pub struct DatabaseEnvironment { pub struct DatabaseEnvironment {
pub env: Environment, pub env: Environment,
pub handle: Result<DbHandle, MdbError>, pub handle: Result<DbHandle, MdbError>,
@ -27,7 +29,7 @@ impl DatabaseEnvironment {
/// of available memory and can be set via the `LMDB_MAP_SIZE` environment variable. /// of available memory and can be set via the `LMDB_MAP_SIZE` environment variable.
/// ///
/// The path of the user can be set with `LMDB_USER`. /// The path of the user can be set with `LMDB_USER`.
pub fn open(env: &str) -> Result<Self, MdbError> { pub fn open() -> Result<Self, MdbError> {
let s = System::new_all(); let s = System::new_all();
let default_map_size: u64 = let default_map_size: u64 =
(s.available_memory() as f32 * MAP_SIZE_MEMORY_RATIO).floor() as u64; (s.available_memory() as f32 * MAP_SIZE_MEMORY_RATIO).floor() as u64;
@ -43,9 +45,10 @@ impl DatabaseEnvironment {
info!("$LMDB_USER={}", user); info!("$LMDB_USER={}", user);
info!("excecuting lmdb open"); info!("excecuting lmdb open");
let file_path: String = format!("/home/{}/.{}/", user, "valentinus"); let file_path: String = format!("/home/{}/.{}/", user, "valentinus");
let env_str = utils::get_release_env().value();
let env: Environment = EnvBuilder::new() let env: Environment = EnvBuilder::new()
.map_size(env_map_size) .map_size(env_map_size)
.open(format!("{}/{}", file_path, env), 0o777) .open(format!("{}/{}", file_path, env_str), 0o777)
.unwrap_or_else(|_| panic!("could not open LMDB at {}", file_path)); .unwrap_or_else(|_| panic!("could not open LMDB at {}", file_path));
let default: Result<DbHandle, MdbError> = env.get_default_db(DbFlags::empty()); let default: Result<DbHandle, MdbError> = env.get_default_db(DbFlags::empty());
if default.is_err() { if default.is_err() {
@ -185,30 +188,18 @@ mod tests {
#[test] #[test]
fn environment_test() -> Result<(), MdbError> { fn environment_test() -> Result<(), MdbError> {
let db = DatabaseEnvironment::open("10-mb-test")?; let db = DatabaseEnvironment::open()?;
const DATA_SIZE_10MB: usize = 10000000; const DATA_SIZE_10MB: usize = 10000000;
let mut data = vec![0u8; DATA_SIZE_10MB]; let mut data = vec![0u8; DATA_SIZE_10MB];
rand::thread_rng().fill_bytes(&mut data); rand::thread_rng().fill_bytes(&mut data);
let k = "test-key".as_bytes(); let k = "test-key".as_bytes();
let expected = &data.to_vec(); let expected = &data.to_vec();
write_chunks(&db.env, &db.handle?, &Vec::from(k), &Vec::from(data))?; write_chunks(&db.env, &db.handle?, &Vec::from(k), &Vec::from(data))?;
let db = DatabaseEnvironment::open("10-mb-test")?; let db = DatabaseEnvironment::open()?;
let actual = DatabaseEnvironment::read(&db.env, &db.handle?, &Vec::from(k)); let actual = DatabaseEnvironment::read(&db.env, &db.handle?, &Vec::from(k));
assert_eq!(expected.to_vec(), actual?); assert_eq!(expected.to_vec(), actual?);
let db = DatabaseEnvironment::open("10-mb-test")?; let db = DatabaseEnvironment::open()?;
let _ = DatabaseEnvironment::delete(&db.env, &db.handle?, &Vec::from(k));
let db = DatabaseEnvironment::open("100-mb-test")?;
const DATA_SIZE_100MB: usize = 100000000;
let mut data = vec![0u8; DATA_SIZE_100MB];
rand::thread_rng().fill_bytes(&mut data);
let k = "test-key".as_bytes();
let expected = &data.to_vec();
write_chunks(&db.env, &db.handle?, &Vec::from(k), &Vec::from(data))?;
let db = DatabaseEnvironment::open("100-mb-test")?;
let actual = DatabaseEnvironment::read(&db.env, &db.handle?, &Vec::from(k));
assert_eq!(expected.to_vec(), actual?);
let db = DatabaseEnvironment::open("100-mb-test")?;
let _ = DatabaseEnvironment::delete(&db.env, &db.handle?, &Vec::from(k)); let _ = DatabaseEnvironment::delete(&db.env, &db.handle?, &Vec::from(k));
Ok(()) Ok(())
} }
} }

View file

@ -3,11 +3,9 @@
use std::error::Error; use std::error::Error;
use crate::{ use crate::{
db, db, error::NevekoError, models::*, monero, utils
models::*,
monero,
utils,
}; };
use kn0sys_lmdb_rs::MdbError;
use log::{ use log::{
debug, debug,
error, error,
@ -16,80 +14,91 @@ use log::{
use rocket::serde::json::Json; use rocket::serde::json::Json;
/// Create a new dispute /// Create a new dispute
pub fn create(d: Json<Dispute>) -> Dispute { pub fn create(d: Json<Dispute>) -> Result<Dispute, MdbError> {
let f_did: String = format!("{}{}", crate::DISPUTE_DB_KEY, utils::generate_rnd()); let f_did: String = format!("{}{}", crate::DISPUTE_DB_KEY, utils::generate_rnd());
info!("create dispute: {}", &f_did); info!("create dispute: {}", &f_did);
let new_dispute = Dispute { let new_dispute = Dispute {
did: String::from(&f_did), did: String::from(&f_did),
created: chrono::offset::Utc::now().timestamp(), created: chrono::offset::Utc::now().timestamp(),
orid: String::from(&d.orid), orid: String::from(&d.orid),
tx_set: String::from(&d.tx_set), tx_set: String::from(&d.tx_set),
}; };
debug!("insert dispute: {:?}", &d); debug!("insert dispute: {:?}", &d);
let s = db::DatabaseEnvironment::open();
let s = db::DatabaseEnvironment::open()?;
let k = &d.did; let k = &d.did;
db::DatabaseEnvironment::write(&s.env, &s.handle, k, &Dispute::to_db(&new_dispute)); let v = bincode::serialize(&new_dispute).unwrap_or_default();
db::write_chunks(&s.env, &s.handle?, k.as_bytes(), &v);
// in order to retrieve all orders, write keys to with dl // in order to retrieve all orders, write keys to with dl
let list_key = crate::DISPUTE_LIST_DB_KEY; let list_key = crate::DISPUTE_LIST_DB_KEY;
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, &String::from(list_key)); let s = db::DatabaseEnvironment::open()?;
let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &list_key.as_bytes().to_vec())?;
if r.is_empty() { if r.is_empty() {
debug!("creating dispute index"); debug!("creating dispute index");
} }
let dispute_list = [String::from(&r), String::from(&f_did)].join(","); let s_r: String = bincode::deserialize(&r[..]).unwrap_or_default();
let dispute_list = [String::from(&s_r), String::from(&f_did)].join(",");
debug!( debug!(
"writing dispute index {} for id: {}", "writing dispute index {} for id: {}",
dispute_list, list_key dispute_list, list_key
); );
db::DatabaseEnvironment::write(&s.env, &s.handle, &String::from(list_key), &dispute_list); let s = db::DatabaseEnvironment::open()?;
db::write_chunks(&s.env, &s.handle?, list_key.as_bytes(), dispute_list.as_bytes());
// restart the dispute aut-settle thread // restart the dispute aut-settle thread
let cleared = is_dispute_clear(r); let cleared = is_dispute_clear(s_r);
if !cleared { if !cleared {
debug!("restarting dispute auto-settle"); debug!("restarting dispute auto-settle");
utils::restart_dispute_auto_settle(); utils::restart_dispute_auto_settle();
} }
new_dispute Ok(new_dispute)
} }
/// Dispute lookup /// Dispute lookup
pub fn find(did: &String) -> Dispute { pub fn find(did: &String) -> Result<Dispute, MdbError> {
let s = db::DatabaseEnvironment::open();
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, &String::from(did)); let s = db::DatabaseEnvironment::open()?;
let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &did.as_bytes().to_vec())?;
if r.is_empty() { if r.is_empty() {
error!("dispute not found"); error!("dispute not found");
return Default::default(); return Err(MdbError::NotFound);
} }
Dispute::from_db(String::from(did), r) let result: Dispute = bincode::deserialize(&r[..]).unwrap_or_default();
Ok(result)
} }
/// Lookup all disputes /// Lookup all disputes
pub fn find_all() -> Vec<Dispute> { pub fn find_all() -> Result<Vec<Dispute>, MdbError> {
let d_s = db::DatabaseEnvironment::open();
let d_s = db::DatabaseEnvironment::open()?;
let d_list_key = crate::DISPUTE_LIST_DB_KEY; let d_list_key = crate::DISPUTE_LIST_DB_KEY;
let d_r = db::DatabaseEnvironment::read(&d_s.env, &d_s.handle, &String::from(d_list_key)); let d_r = db::DatabaseEnvironment::read(&d_s.env, &d_s.handle?, &d_list_key.as_bytes().to_vec())?;
if d_r.is_empty() { if d_r.is_empty() {
error!("dispute index not found"); error!("dispute index not found");
} }
let d_v_did = d_r.split(","); let str_r: String = bincode::deserialize(&d_r[..]).unwrap_or_default();
let d_v_did = str_r.split(",");
let d_v: Vec<String> = d_v_did.map(String::from).collect(); let d_v: Vec<String> = d_v_did.map(String::from).collect();
let mut disputes: Vec<Dispute> = Vec::new(); let mut disputes: Vec<Dispute> = Vec::new();
for o in d_v { for o in d_v {
let dispute: Dispute = find(&o); let dispute: Dispute = find(&o)?;
if !dispute.did.is_empty() { if !dispute.did.is_empty() {
disputes.push(dispute); disputes.push(dispute);
} }
} }
disputes Ok(disputes)
} }
/// Dispute deletion /// Dispute deletion
pub fn delete(did: &String) { pub fn delete(did: &String) -> Result<(), MdbError> {
let s = db::DatabaseEnvironment::open();
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, &String::from(did)); let s = db::DatabaseEnvironment::open()?;
let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &did.as_bytes().to_vec())?;
if r.is_empty() { if r.is_empty() {
error!("dispute not found"); error!("dispute not found");
return Default::default(); return Err(MdbError::NotFound);
} }
db::DatabaseEnvironment::delete(&s.env, &s.handle, &String::from(did)) let s = db::DatabaseEnvironment::open()?;
db::DatabaseEnvironment::delete(&s.env, &s.handle?, did.as_bytes())
} }
/// Triggered on DISPUTE_LAST_CHECK_DB_KEY. /// Triggered on DISPUTE_LAST_CHECK_DB_KEY.
@ -99,30 +108,33 @@ pub fn delete(did: &String) {
/// creation date of the dispute plus the one week /// creation date of the dispute plus the one week
/// ///
/// grace period then the dispute is auto-settled. /// grace period then the dispute is auto-settled.
pub async fn settle_dispute() { pub async fn settle_dispute() -> Result<(), MdbError>{
let tick: std::sync::mpsc::Receiver<()> = let tick: std::sync::mpsc::Receiver<()> =
schedule_recv::periodic_ms(crate::DISPUTE_CHECK_INTERVAL); schedule_recv::periodic_ms(crate::DISPUTE_CHECK_INTERVAL);
loop { loop {
debug!("running dispute auto-settle thread"); debug!("running dispute auto-settle thread");
tick.recv().unwrap(); tick.recv().unwrap();
let s = db::DatabaseEnvironment::open();
let s = db::DatabaseEnvironment::open()?;
let list_key = crate::DISPUTE_LIST_DB_KEY; let list_key = crate::DISPUTE_LIST_DB_KEY;
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, &String::from(list_key)); let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &list_key.as_bytes().to_vec())?;
if r.is_empty() { if r.is_empty() {
info!("dispute index not found"); info!("dispute index not found");
} }
let v_mid = r.split(","); let str_r: String = bincode::deserialize(&r[..]).unwrap_or_default();
let v_mid = str_r.split(",");
let d_vec: Vec<String> = v_mid.map(String::from).collect(); let d_vec: Vec<String> = v_mid.map(String::from).collect();
debug!("dispute contents: {:#?}", d_vec); debug!("dispute contents: {:#?}", d_vec);
let cleared = is_dispute_clear(r); let cleared = is_dispute_clear(str_r);
if cleared { if cleared {
// index was created but cleared // index was created but cleared
info!("terminating dispute auto-settle thread"); info!("terminating dispute auto-settle thread");
db::DatabaseEnvironment::delete(&s.env, &s.handle, list_key); let s = db::DatabaseEnvironment::open()?;
return; db::DatabaseEnvironment::delete(&s.env, &s.handle?, list_key.as_bytes());
return Ok(());
} }
for d in d_vec { for d in d_vec {
let dispute: Dispute = find(&d); let dispute: Dispute = find(&d)?;
if !dispute.did.is_empty() { if !dispute.did.is_empty() {
let now = chrono::offset::Utc::now().timestamp(); let now = chrono::offset::Utc::now().timestamp();
let settle_date = dispute.created + crate::DISPUTE_AUTO_SETTLE as i64; let settle_date = dispute.created + crate::DISPUTE_AUTO_SETTLE as i64;
@ -135,7 +147,7 @@ pub async fn settle_dispute() {
monero::close_wallet(&wallet_name, &wallet_password).await; monero::close_wallet(&wallet_name, &wallet_password).await;
if submit.result.tx_hash_list.is_empty() { if submit.result.tx_hash_list.is_empty() {
error!("could not broadcast txset for dispute: {}", &dispute.did); error!("could not broadcast txset for dispute: {}", &dispute.did);
return; return Ok(());
} }
// remove the dispute from the db // remove the dispute from the db
remove_from_auto_settle(dispute.did); remove_from_auto_settle(dispute.did);
@ -160,15 +172,17 @@ fn is_dispute_clear(r: String) -> bool {
} }
/// clear dispute from index /// clear dispute from index
fn remove_from_auto_settle(did: String) { fn remove_from_auto_settle(did: String) -> Result<(), MdbError> {
info!("removing id {} from disputes", &did); info!("removing id {} from disputes", &did);
let s = db::DatabaseEnvironment::open();
let s = db::DatabaseEnvironment::open()?;
let list_key = crate::DISPUTE_LIST_DB_KEY; let list_key = crate::DISPUTE_LIST_DB_KEY;
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, &String::from(list_key)); let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &list_key.as_bytes().to_vec())?;
if r.is_empty() { if r.is_empty() {
debug!("dispute list index is empty"); debug!("dispute list index is empty");
} }
let pre_v_fts = r.split(","); let str_r: String = bincode::deserialize(&r[..]).unwrap_or_default();
let pre_v_fts = str_r.split(",");
let v: Vec<String> = pre_v_fts let v: Vec<String> = pre_v_fts
.map(|s| { .map(|s| {
if s != &did { if s != &did {
@ -183,7 +197,9 @@ fn remove_from_auto_settle(did: String) {
"writing dipsute index {} for id: {}", "writing dipsute index {} for id: {}",
dispute_list, list_key dispute_list, list_key
); );
db::DatabaseEnvironment::write(&s.env, &s.handle, &String::from(list_key), &dispute_list); let s = db::DatabaseEnvironment::open()?;
db::write_chunks(&s.env, &s.handle?, list_key.as_bytes(), dispute_list.as_bytes());
Ok(())
} }
/// Executes POST /market/dispute/create /// Executes POST /market/dispute/create
@ -227,16 +243,21 @@ async fn transmit_dispute_request(
/// A decomposition trigger for the dispute request so that the logic /// A decomposition trigger for the dispute request so that the logic
/// ///
/// can be executed from the gui. /// can be executed from the gui.
pub async fn trigger_dispute_request(contact: &String, dispute: &Dispute) -> Dispute { pub async fn trigger_dispute_request(contact: &String, dispute: &Dispute) -> Result<Dispute, NevekoError> {
info!("executing trigger_dispute_request"); info!("executing trigger_dispute_request");
let s = db::DatabaseEnvironment::async_open().await;
let s = db::DatabaseEnvironment::open()
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
let k = format!("{}-{}", crate::FTS_JWP_DB_KEY, &contact); let k = format!("{}-{}", crate::FTS_JWP_DB_KEY, &contact);
let jwp = db::DatabaseEnvironment::async_read(&s.env, &s.handle, &k).await; let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
let dispute = transmit_dispute_request(contact, &jwp, dispute).await; let jwp = db::DatabaseEnvironment::read(&s.env, handle, &k.as_bytes().to_vec())
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
let str_jwp: String = bincode::deserialize(&jwp[..]).unwrap_or_default();
let dispute = transmit_dispute_request(contact, &str_jwp, dispute).await;
// handle a failure to create dispute // handle a failure to create dispute
if dispute.is_err() { if dispute.is_err() {
error!("failed to create dispute"); error!("failed to create dispute");
return Default::default(); return Err(NevekoError::Dispute);
} }
dispute.unwrap_or(Default::default()) Ok(dispute.map_err(|_| NevekoError::Dispute)?)
} }

View file

@ -1,11 +1,13 @@
use kn0sys_lmdb_rs::MdbError; use kn0sys_lmdb_rs::MdbError;
use thiserror::Error; use thiserror::Error;
/// Use for mapping errors in functions that can throw multiple errors.
#[derive(Debug, Error)] #[derive(Debug, Error)]
#[error("neveko error. See logs for more info.")] #[error("Neveko error. See logs for more info.")]
pub enum NevekoError { pub enum NevekoError {
///J4I2PRS(J4RsError), ///J4I2PRS(J4RsError),
Database(MdbError), Database(MdbError),
Dispute,
MoneroRpc, MoneroRpc,
MoneroDaemon, MoneroDaemon,
Unknown, Unknown,

View file

@ -81,7 +81,7 @@ pub async fn create_jwp(proof: &TxProof) -> String {
error!("invalid transaction proof"); error!("invalid transaction proof");
return String::new(); return String::new();
} }
let jwp_secret_key = utils::get_jwp_secret_key(); let jwp_secret_key = utils::get_jwp_secret_key().unwrap_or_default();
let key: Hmac<Sha512> = Hmac::new_from_slice(jwp_secret_key.as_bytes()).expect("hash"); let key: Hmac<Sha512> = Hmac::new_from_slice(jwp_secret_key.as_bytes()).expect("hash");
let header = Header { let header = Header {
algorithm: AlgorithmType::Hs512, algorithm: AlgorithmType::Hs512,
@ -122,11 +122,11 @@ pub async fn prove_payment(contact: String, txp: &TxProof) -> Result<reqres::Jwp
match res { match res {
Ok(r) => { Ok(r) => {
// cache the jwp for for fts // cache the jwp for for fts
let env = utils::get_release_env();
let s = db::DatabaseEnvironment::open(&env.value())?; let s = db::DatabaseEnvironment::open()?;
let k = format!("{}-{}", crate::FTS_JWP_DB_KEY, &contact); let k = format!("{}-{}", crate::FTS_JWP_DB_KEY, &contact);
db::DatabaseEnvironment::delete(&s.env, &s.handle?, k.as_bytes())?; db::DatabaseEnvironment::delete(&s.env, &s.handle?, k.as_bytes())?;
let s = db::DatabaseEnvironment::open(&env.value())?; let s = db::DatabaseEnvironment::open()?;
db::write_chunks(&s.env, &s.handle?, &k.as_bytes(), &r.jwp.as_bytes().to_vec()); db::write_chunks(&s.env, &s.handle?, &k.as_bytes(), &r.jwp.as_bytes().to_vec());
Ok(r) Ok(r)
} }
@ -182,7 +182,7 @@ impl<'r> FromRequest<'r> for PaymentProof {
match proof { match proof {
Some(proof) => { Some(proof) => {
// check validity of address, payment amount and tx confirmations // check validity of address, payment amount and tx confirmations
let jwp_secret_key = utils::get_jwp_secret_key(); let jwp_secret_key = utils::get_jwp_secret_key().unwrap_or_default();
let key: Hmac<Sha512> = Hmac::new_from_slice(jwp_secret_key.as_bytes()).expect(""); let key: Hmac<Sha512> = Hmac::new_from_slice(jwp_secret_key.as_bytes()).expect("");
let jwp: Result< let jwp: Result<
Token<jwt::Header, BTreeMap<std::string::String, std::string::String>, _>, Token<jwt::Header, BTreeMap<std::string::String, std::string::String>, _>,

View file

@ -21,8 +21,8 @@ pub fn create(address: &String) -> Result<User, MdbError> {
name: String::new(), name: String::new(),
}; };
debug!("insert user: {:?}", &new_user); debug!("insert user: {:?}", &new_user);
let env = utils::get_release_env();
let s = db::DatabaseEnvironment::open(&env.value())?; let s = db::DatabaseEnvironment::open()?;
let k = &new_user.uid; let k = &new_user.uid;
let v = bincode::serialize(&new_user).unwrap_or_default(); let v = bincode::serialize(&new_user).unwrap_or_default();
db::write_chunks(&s.env, &s.handle?, k.as_bytes(), &v)?; db::write_chunks(&s.env, &s.handle?, k.as_bytes(), &v)?;
@ -31,8 +31,8 @@ pub fn create(address: &String) -> Result<User, MdbError> {
/// User lookup /// User lookup
pub fn find(uid: &String) -> Result<User, MdbError> { pub fn find(uid: &String) -> Result<User, MdbError> {
let env = utils::get_release_env();
let s = db::DatabaseEnvironment::open(&env.value())?; let s = db::DatabaseEnvironment::open()?;
let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &uid.as_bytes().to_vec())?; let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &uid.as_bytes().to_vec())?;
if r.is_empty() { if r.is_empty() {
error!("user not found"); error!("user not found");

View file

@ -11,7 +11,6 @@ use crate::{
monero, monero,
neveko25519, neveko25519,
reqres, reqres,
utils,
}; };
use clap::Parser; use clap::Parser;
use kn0sys_lmdb_rs::MdbError; use kn0sys_lmdb_rs::MdbError;
@ -241,8 +240,8 @@ pub fn get_app_port() -> u16 {
/// i2p http proxy /// i2p http proxy
pub fn get_i2p_http_proxy() -> String { pub fn get_i2p_http_proxy() -> String {
let args = args::Args::parse(); let args = args::Args::parse();
let advanced_proxy = std::env::var(crate::NEVEKO_I2P_PROXY_HOST).unwrap_or(empty_string()); let advanced_proxy = std::env::var(crate::NEVEKO_I2P_PROXY_HOST).unwrap_or(String::new());
if advanced_proxy == empty_string() { if advanced_proxy.is_empty() {
args.i2p_proxy_host args.i2p_proxy_host
} else { } else {
advanced_proxy advanced_proxy
@ -409,20 +408,19 @@ async fn gen_app_wallet(password: &String) {
/// Secret keys for signing internal/external auth tokens /// Secret keys for signing internal/external auth tokens
fn gen_signing_keys() -> Result<(), MdbError> { fn gen_signing_keys() -> Result<(), MdbError> {
info!("generating signing keys"); info!("generating signing keys");
let jwp = get_jwp_secret_key(); let jwp = get_jwp_secret_key()?;
let jwt = get_jwt_secret_key(); let jwt = get_jwt_secret_key()?;
// send to db // send to db
let env = utils::get_release_env();
if jwp.is_empty() { if jwp.is_empty() {
let mut data = [0u8; 32]; let mut data = [0u8; 32];
rand::thread_rng().fill_bytes(&mut data); rand::thread_rng().fill_bytes(&mut data);
let s = db::DatabaseEnvironment::open(&env.value())?; let s = db::DatabaseEnvironment::open()?;
db::write_chunks(&s.env, &s.handle?, crate::NEVEKO_JWP_SECRET_KEY.as_bytes(), &data); db::write_chunks(&s.env, &s.handle?, crate::NEVEKO_JWP_SECRET_KEY.as_bytes(), &data);
} }
if jwt.is_empty() { if jwt.is_empty() {
let mut data = [0u8; 32]; let mut data = [0u8; 32];
rand::thread_rng().fill_bytes(&mut data); rand::thread_rng().fill_bytes(&mut data);
let s = db::DatabaseEnvironment::open(&env.value())?; let s = db::DatabaseEnvironment::open()?;
db::write_chunks(&s.env, &s.handle?, crate::NEVEKO_JWT_SECRET_KEY.as_bytes(), &data); db::write_chunks(&s.env, &s.handle?, crate::NEVEKO_JWT_SECRET_KEY.as_bytes(), &data);
} }
Ok(()) Ok(())
@ -431,52 +429,61 @@ fn gen_signing_keys() -> Result<(), MdbError> {
/// TODO(c2m): add a button to gui to call this /// TODO(c2m): add a button to gui to call this
/// ///
/// dont' forget to generate new keys as well /// dont' forget to generate new keys as well
pub fn revoke_signing_keys() { pub fn revoke_signing_keys() -> Result<(), MdbError> {
let s = db::DatabaseEnvironment::open();
db::DatabaseEnvironment::delete(&s.env, &s.handle, crate::NEVEKO_JWT_SECRET_KEY); let s = db::DatabaseEnvironment::open()?;
db::DatabaseEnvironment::delete(&s.env, &s.handle, crate::NEVEKO_JWP_SECRET_KEY); db::DatabaseEnvironment::delete(&s.env, &s.handle?, crate::NEVEKO_JWT_SECRET_KEY.as_bytes());
let s = db::DatabaseEnvironment::open()?;
db::DatabaseEnvironment::delete(&s.env, &s.handle?, crate::NEVEKO_JWP_SECRET_KEY.as_bytes());
Ok(())
} }
pub fn get_jwt_secret_key() -> String { pub fn get_jwt_secret_key() -> Result<String, MdbError> {
let s = db::DatabaseEnvironment::open();
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, crate::NEVEKO_JWT_SECRET_KEY); let s = db::DatabaseEnvironment::open()?;
let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &crate::NEVEKO_JWT_SECRET_KEY.as_bytes().to_vec())?;
if r.is_empty() { if r.is_empty() {
error!("JWT key not found"); error!("JWT key not found");
return Default::default(); return Err(MdbError::NotFound);
} }
r let result: String = bincode::deserialize(&r[..]).unwrap_or_default();
Ok(result)
} }
pub fn get_jwp_secret_key() -> String { pub fn get_jwp_secret_key() -> Result<String, MdbError> {
let s = db::DatabaseEnvironment::open();
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, crate::NEVEKO_JWP_SECRET_KEY); let s = db::DatabaseEnvironment::open()?;
let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &crate::NEVEKO_JWP_SECRET_KEY.as_bytes().to_vec())?;
if r.is_empty() { if r.is_empty() {
error!("JWP key not found"); error!("JWP key not found");
return Default::default(); return Err(MdbError::NotFound);
} }
r let result: String = bincode::deserialize(&r[..]).unwrap_or_default();
Ok(result)
} }
/// Returns the hex encoded neveko message public key from LMDB /// Returns the hex encoded neveko message public key from LMDB
pub fn get_nmpk() -> String { pub fn get_nmpk() -> Result<String, MdbError> {
let s = db::DatabaseEnvironment::open(); let s = db::DatabaseEnvironment::open()?;
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, crate::NEVEKO_NMPK); let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &crate::NEVEKO_NMPK.as_bytes().to_vec())?;
if r.is_empty() { if r.is_empty() {
error!("neveko message public key not found"); error!("neveko message public key not found");
return Default::default(); return Err(MdbError::NotFound);
} }
r let result: String = bincode::deserialize(&r[..]).unwrap_or_default();
Ok(result)
} }
async fn generate_nmpk() { async fn generate_nmpk() -> Result<(), MdbError> {
info!("generating neveko message public key"); info!("generating neveko message public key");
let nmpk: String = get_nmpk(); let nmpk: String = get_nmpk()?;
// send to db // send to db
let s = db::DatabaseEnvironment::open(); let s = db::DatabaseEnvironment::open()?;
if nmpk.is_empty() { if nmpk.is_empty() {
let nmk: neveko25519::NevekoMessageKeys = neveko25519::generate_neveko_message_keys().await; let nmk: neveko25519::NevekoMessageKeys = neveko25519::generate_neveko_message_keys().await;
db::DatabaseEnvironment::write(&s.env, &s.handle, crate::NEVEKO_NMPK, &nmk.hex_nmpk); db::write_chunks(&s.env, &s.handle?, crate::NEVEKO_NMPK.as_bytes(), nmk.hex_nmpk.as_bytes());
} }
Ok(())
} }
/// Put all app pre-checks here /// Put all app pre-checks here
@ -502,8 +509,8 @@ pub async fn start_up() {
tokio::time::sleep(std::time::Duration::new(5, 0)).await; tokio::time::sleep(std::time::Duration::new(5, 0)).await;
monero::check_rpc_connection().await; monero::check_rpc_connection().await;
let mut wallet_password = let mut wallet_password =
std::env::var(crate::MONERO_WALLET_PASSWORD).unwrap_or(empty_string()); std::env::var(crate::MONERO_WALLET_PASSWORD).unwrap_or_default();
if wallet_password == empty_string() { if wallet_password.is_empty() {
print!( print!(
"MONERO_WALLET_PASSWORD not set, enter neveko wallet password for monero-wallet-rpc: " "MONERO_WALLET_PASSWORD not set, enter neveko wallet password for monero-wallet-rpc: "
); );
@ -572,17 +579,19 @@ pub fn restart_dispute_auto_settle() {
} }
/// Called on app startup if `--clear-fts` flag is passed. /// Called on app startup if `--clear-fts` flag is passed.
fn clear_fts() { fn clear_fts() -> Result<(), MdbError> {
info!("clear fts"); info!("clear fts");
let s = db::DatabaseEnvironment::open(); let s = db::DatabaseEnvironment::open()?;
db::DatabaseEnvironment::delete(&s.env, &s.handle, crate::FTS_DB_KEY); db::DatabaseEnvironment::delete(&s.env, &s.handle?, crate::FTS_DB_KEY.as_bytes());
Ok(())
} }
/// Called on app startup if `--clear-dispute` flag is passed. /// Called on app startup if `--clear-dispute` flag is passed.
fn clear_disputes() { fn clear_disputes() -> Result<(), MdbError> {
info!("clear_disputes"); info!("clear_disputes");
let s = db::DatabaseEnvironment::open(); let s = db::DatabaseEnvironment::open()?;
db::DatabaseEnvironment::delete(&s.env, &s.handle, crate::DISPUTE_LIST_DB_KEY); db::DatabaseEnvironment::delete(&s.env, &s.handle?, crate::DISPUTE_LIST_DB_KEY.as_bytes());
Ok(())
} }
/// ### The highly ineffecient fee estimator. /// ### The highly ineffecient fee estimator.
@ -688,47 +697,54 @@ pub async fn can_transfer(invoice: u128) -> bool {
} }
/// Gui toggle for vendor mode /// Gui toggle for vendor mode
pub fn toggle_vendor_enabled() -> bool { pub fn toggle_vendor_enabled() -> Result<bool, MdbError> {
// TODO(c2m): Dont toggle vendors with orders status != Delivered // TODO(c2m): Dont toggle vendors with orders status != Delivered
let s = db::DatabaseEnvironment::open(); let s = db::DatabaseEnvironment::open()?;
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, contact::NEVEKO_VENDOR_ENABLED); let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &contact::NEVEKO_VENDOR_ENABLED.as_bytes().to_vec())?;
if r != contact::NEVEKO_VENDOR_MODE_ON { let mode: String = bincode::deserialize(&r[..]).unwrap_or_default();
if mode != contact::NEVEKO_VENDOR_MODE_ON {
info!("neveko vendor mode enabled"); info!("neveko vendor mode enabled");
db::DatabaseEnvironment::write( let s = db::DatabaseEnvironment::open()?;
db::write_chunks(
&s.env, &s.env,
&s.handle, &s.handle?,
contact::NEVEKO_VENDOR_ENABLED, contact::NEVEKO_VENDOR_ENABLED.as_bytes(),
contact::NEVEKO_VENDOR_MODE_ON, contact::NEVEKO_VENDOR_MODE_ON.as_bytes(),
); );
true Ok(true)
} else { } else {
info!("neveko vendor mode disabled"); info!("neveko vendor mode disabled");
db::DatabaseEnvironment::write( let s = db::DatabaseEnvironment::open()?;
db::write_chunks(
&s.env, &s.env,
&s.handle, &s.handle?,
contact::NEVEKO_VENDOR_ENABLED, contact::NEVEKO_VENDOR_ENABLED.as_bytes(),
contact::NEVEKO_VENDOR_MODE_OFF, contact::NEVEKO_VENDOR_MODE_OFF.as_bytes(),
); );
false Ok(false)
} }
} }
pub fn search_gui_db(f: String, data: String) -> String { pub fn search_gui_db(f: String, data: String) -> Result<String, MdbError> {
let s = db::DatabaseEnvironment::open(); let s = db::DatabaseEnvironment::open()?;
let k = format!("{}-{}", f, data); let k = format!("{}-{}", f, data);
db::DatabaseEnvironment::read(&s.env, &s.handle, &k) let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &k.as_bytes().to_vec())?;
let result: String = bincode::deserialize(&r[..]).unwrap_or_default();
Ok(result)
} }
pub fn write_gui_db(f: String, key: String, data: String) { pub fn write_gui_db(f: String, key: String, data: String) -> Result<(), MdbError> {
let s = db::DatabaseEnvironment::open(); let s = db::DatabaseEnvironment::open()?;
let k = format!("{}-{}", f, key); let k = format!("{}-{}", f, key);
db::DatabaseEnvironment::write(&s.env, &s.handle, &k, &data); db::write_chunks(&s.env, &s.handle?, k.as_bytes(), data.as_bytes());
Ok(())
} }
pub fn clear_gui_db(f: String, key: String) { pub fn clear_gui_db(f: String, key: String) -> Result<(), MdbError> {
let s = db::DatabaseEnvironment::open(); let s = db::DatabaseEnvironment::open()?;
let k = format!("{}-{}", f, key); let k = format!("{}-{}", f, key);
db::DatabaseEnvironment::delete(&s.env, &s.handle, &k); db::DatabaseEnvironment::delete(&s.env, &s.handle?, k.as_bytes())?;
Ok(())
} }
// Tests // Tests
@ -842,4 +858,4 @@ mod tests {
assert_eq!(expected, actual) assert_eq!(expected, actual)
}); });
} }
} }