mirror of
https://github.com/creating2morrow/neveko.git
synced 2024-12-22 11:39:22 +00:00
more serialization patches and error handling
This commit is contained in:
parent
f8570df9a6
commit
4aa2dcfcba
28 changed files with 773 additions and 555 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -1945,6 +1945,7 @@ dependencies = [
|
|||
name = "neveko_gui"
|
||||
version = "0.1.2-beta"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"chrono",
|
||||
"console_error_panic_hook",
|
||||
"eframe",
|
||||
|
|
|
@ -17,6 +17,6 @@ use neveko_core::{
|
|||
/// Creates user on initial login
|
||||
#[get("/login/<signature>/<aid>/<uid>")]
|
||||
pub async fn login(aid: String, uid: String, signature: String) -> Custom<Json<Authorization>> {
|
||||
let m_auth: Authorization = auth::verify_login(aid, uid, signature).await;
|
||||
Custom(Status::Created, Json(m_auth))
|
||||
let m_auth = auth::verify_login(aid, uid, signature).await;
|
||||
Custom(Status::Created, Json(m_auth.unwrap_or_default()))
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ use neveko_core::{
|
|||
models::*,
|
||||
proof,
|
||||
reqres,
|
||||
utils,
|
||||
};
|
||||
|
||||
/// Add contact
|
||||
|
@ -25,17 +24,18 @@ pub async fn add_contact(
|
|||
_token: auth::BearerToken,
|
||||
) -> Custom<Json<Contact>> {
|
||||
let res_contact = contact::create(&req_contact).await;
|
||||
if res_contact.cid.is_empty() {
|
||||
let u_contact = res_contact.unwrap_or_default();
|
||||
if u_contact.cid.is_empty() {
|
||||
return Custom(Status::BadRequest, Json(Default::default()));
|
||||
}
|
||||
Custom(Status::Ok, Json(res_contact))
|
||||
Custom(Status::Ok, Json(u_contact))
|
||||
}
|
||||
|
||||
/// Return all contacts
|
||||
#[get("/")]
|
||||
pub async fn get_contacts(_token: auth::BearerToken) -> Custom<Json<Vec<Contact>>> {
|
||||
let contacts = contact::find_all();
|
||||
Custom(Status::Ok, Json(contacts))
|
||||
Custom(Status::Ok, Json(contacts.unwrap_or_default()))
|
||||
}
|
||||
|
||||
/// Delete a contact by CID
|
||||
|
@ -44,9 +44,9 @@ pub async fn remove_contact(
|
|||
contact: String,
|
||||
_token: auth::BearerToken,
|
||||
) -> Custom<Json<Vec<Contact>>> {
|
||||
contact::delete(&contact);
|
||||
let _ = contact::delete(&contact);
|
||||
let contacts = contact::find_all();
|
||||
Custom(Status::Ok, Json(contacts))
|
||||
Custom(Status::Ok, Json(contacts.unwrap_or_default()))
|
||||
}
|
||||
|
||||
/// prove payment
|
||||
|
|
|
@ -52,7 +52,7 @@ pub fn create(address: &String) -> Result<Authorization, MdbError> {
|
|||
debug!("insert auth: {:?}", &new_auth);
|
||||
let k = &new_auth.aid.as_bytes();
|
||||
let v = bincode::serialize(&new_auth).unwrap_or_default();
|
||||
db::write_chunks(&s.env, &s.handle?, k, &v);
|
||||
db::write_chunks(&s.env, &s.handle?, k, &v)?;
|
||||
Ok(new_auth)
|
||||
}
|
||||
|
||||
|
@ -83,11 +83,11 @@ fn update_expiration(f_auth: &Authorization, address: &String) -> Result<Authori
|
|||
);
|
||||
|
||||
let s = db::DatabaseEnvironment::open()?;
|
||||
db::DatabaseEnvironment::delete(&s.env, &s.handle?, &u_auth.aid.as_bytes().to_vec());
|
||||
let _ = db::DatabaseEnvironment::delete(&s.env, &s.handle?, &u_auth.aid.as_bytes().to_vec())?;
|
||||
let k = u_auth.aid.as_bytes();
|
||||
let v = bincode::serialize(&u_auth).unwrap_or_default();
|
||||
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)
|
||||
}
|
||||
|
||||
|
@ -126,10 +126,10 @@ pub async fn verify_login(aid: String, uid: String, signature: String) -> Result
|
|||
let u_auth = Authorization::update_uid(f_auth, String::from(&u.uid));
|
||||
|
||||
let s = db::DatabaseEnvironment::open()?;
|
||||
db::DatabaseEnvironment::delete(&s.env, &s.handle?, &u_auth.aid.as_bytes());
|
||||
let _ = db::DatabaseEnvironment::delete(&s.env, &s.handle?, &u_auth.aid.as_bytes())?;
|
||||
let v = bincode::serialize(&u_auth).unwrap_or_default();
|
||||
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;
|
||||
Ok(u_auth)
|
||||
} else if !f_user.xmr_address.is_empty() {
|
||||
|
@ -157,7 +157,7 @@ async fn verify_access(address: &String, signature: &String) -> Result<bool, Mdb
|
|||
let now: i64 = chrono::offset::Utc::now().timestamp();
|
||||
let expiration = get_auth_expiration();
|
||||
if now > f_auth.created + expiration {
|
||||
update_expiration(&f_auth, address);
|
||||
update_expiration(&f_auth, address)?;
|
||||
return Ok(false);
|
||||
}
|
||||
}
|
||||
|
@ -291,7 +291,7 @@ mod tests {
|
|||
|
||||
fn cleanup(k: &String) -> Result<(), MdbError>{
|
||||
let s = db::DatabaseEnvironment::open()?;
|
||||
db::DatabaseEnvironment::delete(&s.env, &s.handle?, k.as_bytes())?;
|
||||
let _ = db::DatabaseEnvironment::delete(&s.env, &s.handle?, k.as_bytes())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
//! contact operations module
|
||||
|
||||
use crate::{
|
||||
db,
|
||||
i2p,
|
||||
models::*,
|
||||
monero,
|
||||
reqres,
|
||||
utils,
|
||||
db, error::NevekoError, i2p, models::*, monero, reqres, utils
|
||||
};
|
||||
use kn0sys_lmdb_rs::MdbError;
|
||||
use log::{
|
||||
|
@ -43,7 +38,7 @@ pub async fn create(c: &Json<Contact>) -> Result<Contact, MdbError> {
|
|||
let s = db::DatabaseEnvironment::open()?;
|
||||
let k = &new_contact.cid;
|
||||
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
|
||||
let list_key = crate::CONTACT_LIST_DB_KEY;
|
||||
let str_lk = String::from(list_key);
|
||||
|
@ -60,7 +55,7 @@ pub async fn create(c: &Json<Contact>) -> Result<Contact, MdbError> {
|
|||
contact_list, list_key
|
||||
);
|
||||
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)
|
||||
}
|
||||
|
||||
|
@ -78,14 +73,14 @@ pub fn find(cid: &String) -> Result<Contact, MdbError> {
|
|||
}
|
||||
|
||||
/// Contact lookup
|
||||
pub fn find_by_i2p_address(i2p_address: &String) -> Result<Contact , MdbError> {
|
||||
let contacts = find_all()?;
|
||||
pub fn find_by_i2p_address(i2p_address: &String) -> Result<Contact , NevekoError> {
|
||||
let contacts = find_all().map_err(|_| NevekoError::Database(MdbError::NotFound))?;
|
||||
for c in contacts {
|
||||
if c.i2p_address == *i2p_address {
|
||||
return Ok(c);
|
||||
}
|
||||
}
|
||||
Err(MdbError::NotFound)
|
||||
Err(NevekoError::Database(MdbError::NotFound))
|
||||
}
|
||||
|
||||
/// Contact deletion
|
||||
|
@ -98,7 +93,7 @@ pub fn delete(cid: &String) -> Result<(), MdbError> {
|
|||
return Err(MdbError::NotFound);
|
||||
}
|
||||
let s = db::DatabaseEnvironment::open()?;
|
||||
db::DatabaseEnvironment::delete(&s.env, &s.handle?, cid.as_bytes());
|
||||
let _ = db::DatabaseEnvironment::delete(&s.env, &s.handle?, cid.as_bytes())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -142,10 +137,11 @@ async fn validate_contact(j: &Json<Contact>) -> bool {
|
|||
}
|
||||
|
||||
/// Send our information
|
||||
pub async fn share() -> Result<Contact, MdbError> {
|
||||
|
||||
let s = db::DatabaseEnvironment::open()?;
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &NEVEKO_VENDOR_ENABLED.as_bytes().to_vec())?;
|
||||
pub async fn share() -> Result<Contact, NevekoError> {
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let r = db::DatabaseEnvironment::read(&s.env, handle, &NEVEKO_VENDOR_ENABLED.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let str_r: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
let is_vendor = str_r == NEVEKO_VENDOR_MODE_ON;
|
||||
let wallet_name = String::from(crate::APP_NAME);
|
||||
|
@ -235,7 +231,7 @@ mod tests {
|
|||
fn cleanup(k: &String) {
|
||||
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
db::DatabaseEnvironment::delete(&s.env, &s.handle, k);
|
||||
let _ = db::DatabaseEnvironment::delete(&s.env, &s.handle, k)?;
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -19,7 +19,11 @@ const CHUNK_SIZE_MEMORY_RATIO: f32 = MAP_SIZE_MEMORY_RATIO * 0.01;
|
|||
///
|
||||
/// By default the database will be written to /home/user/.neveko/{ENV}/lmdb
|
||||
pub struct DatabaseEnvironment {
|
||||
/// Represents LMDB Environment.
|
||||
//TODO(n12n): cache the DB handle to avoid multiple open ops
|
||||
pub env: Environment,
|
||||
/// DB handle.
|
||||
// TODO(n12n): cache the DB handle to avoid multiple open ops
|
||||
pub handle: Result<DbHandle, MdbError>,
|
||||
}
|
||||
|
||||
|
@ -199,7 +203,7 @@ mod tests {
|
|||
let actual = DatabaseEnvironment::read(&db.env, &db.handle?, &Vec::from(k));
|
||||
assert_eq!(expected.to_vec(), actual?);
|
||||
let db = DatabaseEnvironment::open()?;
|
||||
let _ = DatabaseEnvironment::delete(&db.env, &db.handle?, &Vec::from(k));
|
||||
let _ = DatabaseEnvironment::delete(&db.env, &db.handle?, &Vec::from(k))?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -28,7 +28,7 @@ pub fn create(d: Json<Dispute>) -> Result<Dispute, MdbError> {
|
|||
let s = db::DatabaseEnvironment::open()?;
|
||||
let k = &d.did;
|
||||
let v = bincode::serialize(&new_dispute).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 orders, write keys to with dl
|
||||
let list_key = crate::DISPUTE_LIST_DB_KEY;
|
||||
let s = db::DatabaseEnvironment::open()?;
|
||||
|
@ -43,7 +43,7 @@ pub fn create(d: Json<Dispute>) -> Result<Dispute, MdbError> {
|
|||
dispute_list, list_key
|
||||
);
|
||||
let s = db::DatabaseEnvironment::open()?;
|
||||
db::write_chunks(&s.env, &s.handle?, list_key.as_bytes(), dispute_list.as_bytes());
|
||||
db::write_chunks(&s.env, &s.handle?, list_key.as_bytes(), dispute_list.as_bytes())?;
|
||||
// restart the dispute aut-settle thread
|
||||
let cleared = is_dispute_clear(s_r);
|
||||
if !cleared {
|
||||
|
@ -130,7 +130,7 @@ pub async fn settle_dispute() -> Result<(), MdbError>{
|
|||
// index was created but cleared
|
||||
info!("terminating dispute auto-settle thread");
|
||||
let s = db::DatabaseEnvironment::open()?;
|
||||
db::DatabaseEnvironment::delete(&s.env, &s.handle?, list_key.as_bytes());
|
||||
let _ = db::DatabaseEnvironment::delete(&s.env, &s.handle?, list_key.as_bytes())?;
|
||||
return Ok(());
|
||||
}
|
||||
for d in d_vec {
|
||||
|
@ -150,7 +150,7 @@ pub async fn settle_dispute() -> Result<(), MdbError>{
|
|||
return Ok(());
|
||||
}
|
||||
// remove the dispute from the db
|
||||
remove_from_auto_settle(dispute.did);
|
||||
remove_from_auto_settle(dispute.did)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ fn remove_from_auto_settle(did: String) -> Result<(), MdbError> {
|
|||
dispute_list, list_key
|
||||
);
|
||||
let s = db::DatabaseEnvironment::open()?;
|
||||
db::write_chunks(&s.env, &s.handle?, list_key.as_bytes(), dispute_list.as_bytes());
|
||||
db::write_chunks(&s.env, &s.handle?, list_key.as_bytes(), dispute_list.as_bytes())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ pub enum NevekoError {
|
|||
Dispute,
|
||||
I2P,
|
||||
J4I2PRS,
|
||||
Message,
|
||||
MoneroRpc,
|
||||
MoneroDaemon,
|
||||
Nasr,
|
||||
|
|
|
@ -21,6 +21,8 @@ use std::{
|
|||
time::Duration,
|
||||
};
|
||||
|
||||
const TODO: &str = "test";
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct HttpProxyStatus {
|
||||
pub open: bool,
|
||||
|
@ -99,8 +101,7 @@ async fn find_tunnels() {
|
|||
/// proxy tunnel, etc. Logs proxy status every 10 minutes.
|
||||
pub async fn start() {
|
||||
info!("starting i2p-zero");
|
||||
let args = args::Args::parse();
|
||||
let path = args.i2p_zero_dir;
|
||||
let path = TODO;
|
||||
let output = Command::new(format!("{}/router/bin/i2p-zero", path)).spawn();
|
||||
match output {
|
||||
Ok(child) => debug!("{:?}", child.stdout),
|
||||
|
@ -125,8 +126,7 @@ pub async fn start() {
|
|||
/// Create an i2p tunnel for the NEVEKO application
|
||||
fn create_tunnel() {
|
||||
info!("creating tunnel");
|
||||
let args = args::Args::parse();
|
||||
let path = args.i2p_zero_dir;
|
||||
let path = TODO;
|
||||
let output = Command::new(format!("{}/router/bin/tunnel-control.sh", path))
|
||||
.args([
|
||||
"server.create",
|
||||
|
@ -141,8 +141,7 @@ fn create_tunnel() {
|
|||
/// Create an i2p tunnel for the monero wallet socks proxy
|
||||
fn create_socks_proxy_tunnel() {
|
||||
info!("creating monerod socks proxy tunnel");
|
||||
let args = args::Args::parse();
|
||||
let path = args.i2p_zero_dir;
|
||||
let path = TODO;
|
||||
let output = Command::new(format!("{}/router/bin/tunnel-control.sh", path))
|
||||
.args(["socks.create", &get_i2p_socks_proxy_port().to_string()])
|
||||
.spawn()
|
||||
|
@ -154,7 +153,7 @@ fn create_socks_proxy_tunnel() {
|
|||
fn create_anon_inbound_tunnel() {
|
||||
info!("creating monerod anon inbound proxy tunnel");
|
||||
let args = args::Args::parse();
|
||||
let path = args.i2p_zero_dir;
|
||||
let path = TODO;
|
||||
let output = Command::new(format!("{}/router/bin/tunnel-control.sh", path))
|
||||
.args([
|
||||
"server.create",
|
||||
|
@ -186,8 +185,7 @@ fn get_i2p_socks_proxy_port() -> String {
|
|||
|
||||
/// Create the http proxy if it doesn't exist
|
||||
fn create_http_proxy() {
|
||||
let args = args::Args::parse();
|
||||
let path = args.i2p_zero_dir;
|
||||
let path = TODO;
|
||||
info!("creating http proxy");
|
||||
let port = get_i2p_proxy_port();
|
||||
let output = Command::new(format!("{}/router/bin/tunnel-control.sh", path))
|
||||
|
@ -242,8 +240,7 @@ pub fn get_destination(port: Option<u16>) -> String {
|
|||
|
||||
/// Ping the i2p-zero http proxy `tunnel-control http.state <port>`
|
||||
pub async fn check_connection() -> ProxyStatus {
|
||||
let args = args::Args::parse();
|
||||
let path = args.i2p_zero_dir;
|
||||
let path = TODO;
|
||||
let port = get_i2p_proxy_port();
|
||||
let output = Command::new(format!("{}/router/bin/tunnel-control.sh", path))
|
||||
.args(["http.state", &port])
|
||||
|
|
|
@ -3,14 +3,16 @@
|
|||
use crate::{
|
||||
contact,
|
||||
db,
|
||||
error::NevekoError,
|
||||
i2p,
|
||||
models::*,
|
||||
monero,
|
||||
neveko25519,
|
||||
order,
|
||||
reqres,
|
||||
utils,
|
||||
utils
|
||||
};
|
||||
use kn0sys_lmdb_rs::MdbError;
|
||||
use log::{
|
||||
debug,
|
||||
error,
|
||||
|
@ -44,7 +46,7 @@ struct MultisigMessageData {
|
|||
}
|
||||
|
||||
/// Create a new message
|
||||
pub async fn create(m: Json<Message>, jwp: String, m_type: MessageType) -> Message {
|
||||
pub async fn create(m: Json<Message>, jwp: String, m_type: MessageType) -> Result<Message, NevekoError> {
|
||||
let rnd = utils::generate_rnd();
|
||||
let mut f_mid: String = format!("{}{}", crate::MESSAGE_DB_KEY, &rnd);
|
||||
if m_type == MessageType::Multisig {
|
||||
|
@ -52,9 +54,9 @@ pub async fn create(m: Json<Message>, jwp: String, m_type: MessageType) -> Messa
|
|||
}
|
||||
info!("creating message: {}", &f_mid);
|
||||
let created = chrono::offset::Utc::now().timestamp();
|
||||
// get contact public gpg key and encipher the message
|
||||
// get contact public message key and encipher the message
|
||||
debug!("sending message: {:?}", &m);
|
||||
let contact: Contact = contact::find(&m.to);
|
||||
let contact: Contact = contact::find(&m.to).map_err(|_| NevekoError::Message)?;
|
||||
let hex_nmpk: String = contact.nmpk;
|
||||
let encipher = Some(String::from(neveko25519::ENCIPHER));
|
||||
let e_body = neveko25519::cipher(&hex_nmpk, String::from(&m.body), encipher).await;
|
||||
|
@ -67,35 +69,47 @@ pub async fn create(m: Json<Message>, jwp: String, m_type: MessageType) -> Messa
|
|||
to: String::from(&m.to),
|
||||
};
|
||||
debug!("insert message: {:?}", &new_message);
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let k = &new_message.mid;
|
||||
db::DatabaseEnvironment::write(&s.env, &s.handle, k, &Message::to_db(&new_message));
|
||||
let message = bincode::serialize(&new_message).unwrap_or_default();
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
db::write_chunks(&s.env, handle, k.as_bytes(), &message)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
// in order to retrieve all message, write keys to with ml
|
||||
let list_key = crate::MESSAGE_LIST_DB_KEY;
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, &String::from(list_key));
|
||||
let r = db::DatabaseEnvironment::read(&s.env, handle, &list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if r.is_empty() {
|
||||
debug!("creating message index");
|
||||
}
|
||||
let msg_list = [r, String::from(&f_mid)].join(",");
|
||||
let d_r: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
let msg_list = [d_r, String::from(&f_mid)].join(",");
|
||||
debug!("writing message index {} for id: {}", msg_list, list_key);
|
||||
db::DatabaseEnvironment::write(&s.env, &s.handle, &String::from(list_key), &msg_list);
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
db::write_chunks(&s.env, handle, list_key.as_bytes(), msg_list.as_bytes())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
info!("attempting to send message");
|
||||
let send = send_message(&new_message, &jwp, m_type).await;
|
||||
send.unwrap();
|
||||
new_message
|
||||
Ok(new_message)
|
||||
}
|
||||
|
||||
/// Rx message
|
||||
pub async fn rx(m: Json<Message>) {
|
||||
pub async fn rx(m: Json<Message>) -> Result<(), NevekoError>{
|
||||
info!("rx from: {}", &m.from);
|
||||
// make sure the message isn't something strange
|
||||
let is_valid = validate_message(&m);
|
||||
if !is_valid {
|
||||
return;
|
||||
error!("invalid contact");
|
||||
return Err(NevekoError::Contact);
|
||||
}
|
||||
// don't allow messages from outside the contact list
|
||||
let is_in_contact_list = contact::exists(&m.from);
|
||||
let is_in_contact_list = contact::exists(&m.from)
|
||||
.map_err(|_| NevekoError::Contact)?;
|
||||
if !is_in_contact_list {
|
||||
return;
|
||||
error!("not a mutual contact");
|
||||
return Err(NevekoError::Contact);
|
||||
}
|
||||
let f_mid: String = format!("{}{}", crate::MESSAGE_DB_KEY, utils::generate_rnd());
|
||||
let new_message = Message {
|
||||
|
@ -107,30 +121,41 @@ pub async fn rx(m: Json<Message>) {
|
|||
to: String::from(&m.to),
|
||||
};
|
||||
debug!("insert message: {:?}", &new_message);
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let k = &new_message.mid;
|
||||
db::DatabaseEnvironment::write(&s.env, &s.handle, k, &Message::to_db(&new_message));
|
||||
let message = bincode::serialize(&new_message).unwrap_or_default();
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
db::write_chunks(&s.env, handle, k.as_bytes(), &message)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
// in order to retrieve all message, write keys to with rx
|
||||
let list_key = crate::RX_MESSAGE_DB_KEY;
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, &String::from(list_key));
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let r = db::DatabaseEnvironment::read(&s.env, handle, &list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if r.is_empty() {
|
||||
debug!("creating message index");
|
||||
}
|
||||
let msg_list = [r, String::from(&f_mid)].join(",");
|
||||
let old: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
let msg_list = [old, String::from(&f_mid)].join(",");
|
||||
debug!("writing message index {} for {}", msg_list, list_key);
|
||||
db::DatabaseEnvironment::write(&s.env, &s.handle, &String::from(list_key), &msg_list);
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
db::write_chunks(&s.env, handle, list_key.as_bytes(), msg_list.as_bytes())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Parse the multisig message type and info
|
||||
async fn parse_multisig_message(mid: String) -> MultisigMessageData {
|
||||
let d: reqres::DecipheredMessageBody = decipher_body(mid).await;
|
||||
async fn parse_multisig_message(mid: String) -> Result<MultisigMessageData, NevekoError> {
|
||||
let d: reqres::DecipheredMessageBody = decipher_body(mid).await?;
|
||||
let mut bytes = hex::decode(d.body.into_bytes()).unwrap_or_default();
|
||||
let decoded = String::from_utf8(bytes).unwrap_or(String::new());
|
||||
let values = decoded.split(":");
|
||||
let mut v: Vec<String> = values.map(String::from).collect();
|
||||
if v.len() != VALID_MSIG_MSG_LENGTH {
|
||||
error!("invalid msig message length");
|
||||
return Default::default();
|
||||
return Err(NevekoError::Message);
|
||||
}
|
||||
let sub_type: String = v.remove(0);
|
||||
let orid: String = v.remove(0);
|
||||
|
@ -144,11 +169,13 @@ async fn parse_multisig_message(mid: String) -> MultisigMessageData {
|
|||
}
|
||||
bytes = Vec::new();
|
||||
debug!("zero decipher bytes: {:?}", bytes);
|
||||
MultisigMessageData {
|
||||
info,
|
||||
sub_type,
|
||||
orid,
|
||||
}
|
||||
Ok(
|
||||
MultisigMessageData {
|
||||
info,
|
||||
sub_type,
|
||||
orid,
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/// Rx multisig message
|
||||
|
@ -171,16 +198,20 @@ async fn parse_multisig_message(mid: String) -> MultisigMessageData {
|
|||
/// let key = "prepare-o123-test.b32.i2p";
|
||||
/// let info_str = db::DatabaseEnvironment::read(&s.env, &s.handle, &key);
|
||||
/// ```
|
||||
pub async fn rx_multisig(m: Json<Message>) {
|
||||
pub async fn rx_multisig(m: Json<Message>) -> Result<(), NevekoError> {
|
||||
info!("rx multisig from: {}", &m.from);
|
||||
// make sure the message isn't something strange
|
||||
let is_valid = validate_message(&m);
|
||||
if !is_valid {
|
||||
return;
|
||||
error!("invalid contact");
|
||||
return Err(NevekoError::Contact);
|
||||
}
|
||||
// don't allow messages from outside the contact list
|
||||
let is_in_contact_list = contact::exists(&m.from);
|
||||
let is_in_contact_list = contact::exists(&m.from)
|
||||
.map_err(|_| NevekoError::Contact)?;
|
||||
if !is_in_contact_list {
|
||||
return;
|
||||
error!("not a mutual contact");
|
||||
return Err(NevekoError::Contact);
|
||||
}
|
||||
let f_mid: String = format!("msig{}", utils::generate_rnd());
|
||||
let new_message = Message {
|
||||
|
@ -191,76 +222,99 @@ pub async fn rx_multisig(m: Json<Message>) {
|
|||
created: chrono::offset::Utc::now().timestamp(),
|
||||
to: String::from(&m.to),
|
||||
};
|
||||
let s = db::DatabaseEnvironment::async_open().await;
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let k = &new_message.mid;
|
||||
db::DatabaseEnvironment::async_write(&s.env, &s.handle, k, &Message::to_db(&new_message)).await;
|
||||
let message = bincode::serialize(&new_message).unwrap_or_default();
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
db::write_chunks(&s.env, handle, k.as_bytes(), &message)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
// in order to retrieve all msig messages, write keys to with msigl
|
||||
let list_key = crate::MSIG_MESSAGE_LIST_DB_KEY;
|
||||
let r = db::DatabaseEnvironment::async_read(&s.env, &s.handle, &String::from(list_key)).await;
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let r = db::DatabaseEnvironment::read(&s.env, handle, &list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if r.is_empty() {
|
||||
debug!("creating msig message index");
|
||||
}
|
||||
let msg_list = [r, String::from(&f_mid)].join(",");
|
||||
let old: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
let msg_list = [old, String::from(&f_mid)].join(",");
|
||||
debug!(
|
||||
"writing msig message index {} for id: {}",
|
||||
msg_list, list_key
|
||||
);
|
||||
db::DatabaseEnvironment::async_write(&s.env, &s.handle, &String::from(list_key), &msg_list).await;
|
||||
let data: MultisigMessageData = parse_multisig_message(new_message.mid).await;
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
db::write_chunks(&s.env, handle, list_key.as_bytes(), msg_list.as_bytes())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let data: MultisigMessageData = parse_multisig_message(new_message.mid).await?;
|
||||
debug!(
|
||||
"writing multisig message type {} for order {}",
|
||||
&data.sub_type, &data.orid
|
||||
);
|
||||
// lookup msig message data by {type}-{order id}-{contact .b32.i2p address}
|
||||
// store info as {a_info}:{a_info (optional)}
|
||||
let s_msig = db::DatabaseEnvironment::async_open().await;
|
||||
let s_msig = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let msig_key = format!("{}-{}-{}", &data.sub_type, &data.orid, &m.from);
|
||||
db::DatabaseEnvironment::async_write(&s_msig.env, &s_msig.handle, &msig_key, &data.info).await;
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
db::write_chunks(&s_msig.env, handle, msig_key.as_bytes(), data.info.as_bytes())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Message lookup
|
||||
pub fn find(mid: &String) -> Message {
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, &String::from(mid));
|
||||
/// Message lookup()
|
||||
pub fn find(mid: &String) -> Result<Message, NevekoError> {
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let r = db::DatabaseEnvironment::read(&s.env, handle, &mid.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if r.is_empty() {
|
||||
error!("message not found");
|
||||
return Default::default();
|
||||
return Err(NevekoError::Message);
|
||||
}
|
||||
Message::from_db(String::from(mid), r)
|
||||
let result: Message = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// Message lookup
|
||||
pub fn find_all() -> Vec<Message> {
|
||||
let i_s = db::DatabaseEnvironment::open();
|
||||
pub fn find_all() -> Result<Vec<Message>, NevekoError> {
|
||||
let i_s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let i_list_key = crate::MESSAGE_LIST_DB_KEY;
|
||||
let i_r = db::DatabaseEnvironment::read(&i_s.env, &i_s.handle, &String::from(i_list_key));
|
||||
let handle = &i_s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let i_r = db::DatabaseEnvironment::read(&i_s.env, handle, &i_list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if i_r.is_empty() {
|
||||
error!("message index not found");
|
||||
}
|
||||
let i_r: String = bincode::deserialize(&i_r[..]).unwrap_or_default();
|
||||
let i_v_mid = i_r.split(",");
|
||||
let i_v: Vec<String> = i_v_mid.map(String::from).collect();
|
||||
let mut messages: Vec<Message> = Vec::new();
|
||||
for m in i_v {
|
||||
let message: Message = find(&m);
|
||||
let message: Message = find(&m)?;
|
||||
if !message.mid.is_empty() {
|
||||
messages.push(message);
|
||||
}
|
||||
}
|
||||
let o_list_key = crate::RX_MESSAGE_DB_KEY;
|
||||
let o_s = db::DatabaseEnvironment::open();
|
||||
let o_r = db::DatabaseEnvironment::read(&o_s.env, &o_s.handle, &String::from(o_list_key));
|
||||
let o_s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &o_s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let o_r = db::DatabaseEnvironment::read(&o_s.env, handle, &o_list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if o_r.is_empty() {
|
||||
error!("message index not found");
|
||||
}
|
||||
let o_r: String = bincode::deserialize(&o_r[..]).unwrap_or_default();
|
||||
let o_v_mid = o_r.split(",");
|
||||
let o_v: Vec<String> = o_v_mid.map(String::from).collect();
|
||||
for m in o_v {
|
||||
let message: Message = find(&m);
|
||||
let message: Message = find(&m)?;
|
||||
if !message.mid.is_empty() {
|
||||
messages.push(message);
|
||||
}
|
||||
}
|
||||
messages
|
||||
Ok(messages)
|
||||
}
|
||||
|
||||
/// Tx message
|
||||
|
@ -288,7 +342,7 @@ async fn send_message(out: &Message, jwp: &str, m_type: MessageType) -> Result<(
|
|||
let status = response.status();
|
||||
debug!("send response: {:?}", status.as_str());
|
||||
if status == StatusCode::OK || status == StatusCode::PAYMENT_REQUIRED {
|
||||
remove_from_fts(String::from(&out.mid));
|
||||
remove_from_fts(String::from(&out.mid))?;
|
||||
Ok(())
|
||||
} else {
|
||||
Ok(())
|
||||
|
@ -300,25 +354,28 @@ async fn send_message(out: &Message, jwp: &str, m_type: MessageType) -> Result<(
|
|||
}
|
||||
}
|
||||
} else {
|
||||
send_to_retry(String::from(&out.mid)).await;
|
||||
send_to_retry(String::from(&out.mid)).await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns deciphered message
|
||||
pub async fn decipher_body(mid: String) -> reqres::DecipheredMessageBody {
|
||||
let m = find(&mid);
|
||||
let contact = contact::find_by_i2p_address(&m.from);
|
||||
pub async fn decipher_body(mid: String) -> Result<reqres::DecipheredMessageBody, NevekoError> {
|
||||
let m = find(&mid)?;
|
||||
let contact = contact::find_by_i2p_address(&m.from)?;
|
||||
let nmpk = contact.nmpk;
|
||||
let message = String::from(&m.body);
|
||||
let body = neveko25519::cipher(&nmpk, message, None).await;
|
||||
reqres::DecipheredMessageBody { mid, body }
|
||||
Ok(reqres::DecipheredMessageBody { mid, body })
|
||||
}
|
||||
|
||||
/// Message deletion
|
||||
pub fn delete(mid: &String) {
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
db::DatabaseEnvironment::delete(&s.env, &s.handle, &String::from(mid));
|
||||
pub fn delete(mid: &String) -> Result<(), NevekoError> {
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let _ = db::DatabaseEnvironment::delete(&s.env, handle, mid.as_bytes())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// ping the contact health check over i2p
|
||||
|
@ -354,48 +411,60 @@ async fn is_contact_online(contact: &String, jwp: String) -> Result<bool, Box<dy
|
|||
}
|
||||
|
||||
/// stage message for async retry
|
||||
async fn send_to_retry(mid: String) {
|
||||
async fn send_to_retry(mid: String) -> Result<(), NevekoError>{
|
||||
info!("sending {} to fts", &mid);
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
// in order to retrieve FTS (failed-to-send), write keys to db with fts
|
||||
let list_key = crate::FTS_DB_KEY;
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, &String::from(list_key));
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let r = db::DatabaseEnvironment::read(&s.env, handle, &list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if r.is_empty() {
|
||||
debug!("creating fts message index");
|
||||
}
|
||||
let mut msg_list = [String::from(&r), String::from(&mid)].join(",");
|
||||
let i_r: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
let mut msg_list = [String::from(&i_r), String::from(&mid)].join(",");
|
||||
// don't duplicate message ids in fts
|
||||
if String::from(&r).contains(&String::from(&mid)) {
|
||||
msg_list = r;
|
||||
if String::from(&i_r).contains(&String::from(&mid)) {
|
||||
msg_list = i_r;
|
||||
}
|
||||
debug!(
|
||||
"writing fts message index {} for id: {}",
|
||||
msg_list, list_key
|
||||
);
|
||||
db::DatabaseEnvironment::write(&s.env, &s.handle, &String::from(list_key), &msg_list);
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
db::write_chunks(&s.env, handle, list_key.as_bytes(), msg_list.as_bytes())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
// restart fts if not empty
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, &String::from(list_key));
|
||||
let v_mid = r.split(",");
|
||||
let r = db::DatabaseEnvironment::read(&s.env, handle, &list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let str_r: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
let v_mid = str_r.split(",");
|
||||
let v: Vec<String> = v_mid.map(String::from).collect();
|
||||
debug!("fts contents: {:#?}", v);
|
||||
let cleared = is_fts_clear(r);
|
||||
let cleared = is_fts_clear(str_r);
|
||||
if !cleared {
|
||||
debug!("restarting fts");
|
||||
utils::restart_retry_fts();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// clear fts message from index
|
||||
fn remove_from_fts(mid: String) {
|
||||
fn remove_from_fts(mid: String) -> Result<(), NevekoError> {
|
||||
info!("removing id {} from fts", &mid);
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
// in order to retrieve FTS (failed-to-send), write keys to with fts
|
||||
let list_key = crate::FTS_DB_KEY;
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, &String::from(list_key));
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let r = db::DatabaseEnvironment::read(&s.env, handle, &list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if r.is_empty() {
|
||||
debug!("fts is empty");
|
||||
}
|
||||
let pre_v_fts = r.split(",");
|
||||
let s_r: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
let pre_v_fts = s_r.split(",");
|
||||
let v: Vec<String> = pre_v_fts
|
||||
.map(|s| {
|
||||
if s != &mid {
|
||||
|
@ -410,7 +479,11 @@ fn remove_from_fts(mid: String) {
|
|||
"writing fts message index {} for id: {}",
|
||||
msg_list, list_key
|
||||
);
|
||||
db::DatabaseEnvironment::write(&s.env, &s.handle, &String::from(list_key), &msg_list);
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
db::write_chunks(&s.env, handle, list_key.as_bytes(), msg_list.as_bytes())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Triggered on app startup, retries to send fts every minute
|
||||
|
@ -418,42 +491,51 @@ fn remove_from_fts(mid: String) {
|
|||
/// FTS thread terminates when empty and gets restarted on the next
|
||||
///
|
||||
/// failed-to-send message.
|
||||
pub async fn retry_fts() {
|
||||
pub async fn retry_fts() -> Result<(), NevekoError> {
|
||||
let tick: std::sync::mpsc::Receiver<()> = schedule_recv::periodic_ms(crate::FTS_RETRY_INTERVAL);
|
||||
loop {
|
||||
debug!("running retry failed-to-send thread");
|
||||
tick.recv().unwrap();
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let list_key = crate::FTS_DB_KEY;
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, &String::from(list_key));
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let r = db::DatabaseEnvironment::read(&s.env, handle, &list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if r.is_empty() {
|
||||
info!("fts message index not found");
|
||||
break; // terminate fts if no message to send
|
||||
break Err(NevekoError::Database(MdbError::NotFound)); // terminate fts if no message to send
|
||||
}
|
||||
let v_mid = r.split(",");
|
||||
let s_r: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
let v_mid = s_r.split(",");
|
||||
let v: Vec<String> = v_mid.map(String::from).collect();
|
||||
debug!("fts contents: {:#?}", v);
|
||||
let cleared = is_fts_clear(r);
|
||||
let cleared = is_fts_clear(s_r);
|
||||
if cleared {
|
||||
// index was created but cleared
|
||||
info!("terminating retry fts thread");
|
||||
db::DatabaseEnvironment::delete(&s.env, &s.handle, list_key);
|
||||
break;
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let _ = db::DatabaseEnvironment::delete(&s.env, handle, &list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
break Err(NevekoError::Database(MdbError::NotFound));
|
||||
}
|
||||
for m in v {
|
||||
let message: Message = find(&m);
|
||||
let message: Message = find(&m)?;
|
||||
if !message.mid.is_empty() {
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
// get jwp from db
|
||||
let k = format!("{}-{}", crate::FTS_JWP_DB_KEY, &message.to);
|
||||
let jwp = db::DatabaseEnvironment::read(&s.env, &s.handle, &k);
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let jwp = db::DatabaseEnvironment::read(&s.env, handle, &k.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if !jwp.is_empty() {
|
||||
let m_type = if message.mid.contains("msig") {
|
||||
MessageType::Multisig
|
||||
} else {
|
||||
MessageType::Normal
|
||||
};
|
||||
send_message(&message, &jwp, m_type).await.unwrap();
|
||||
let str_jwp: String = bincode::deserialize(&jwp[..]).unwrap_or_default();
|
||||
send_message(&message, &str_jwp, m_type).await.unwrap();
|
||||
} else {
|
||||
error!("not jwp found for fts id: {}", &message.mid);
|
||||
}
|
||||
|
@ -488,14 +570,16 @@ fn is_fts_clear(r: String) -> bool {
|
|||
/// Enciphers and sends the output from the monero-rpc
|
||||
///
|
||||
/// `prepare_multisig_info` method.
|
||||
pub async fn send_prepare_info(orid: &String, contact: &String) {
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
pub async fn send_prepare_info(orid: &String, contact: &String) -> Result<(), NevekoError> {
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let wallet_name = String::from(orid);
|
||||
let wallet_password = String::new();
|
||||
monero::open_wallet(&wallet_name, &wallet_password).await;
|
||||
let prepare_info = monero::prepare_wallet().await;
|
||||
let k = format!("{}-{}", crate::FTS_JWP_DB_KEY, contact);
|
||||
let jwp = db::DatabaseEnvironment::read(&s.env, &s.handle, &k);
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let jwp = db::DatabaseEnvironment::read(&s.env, handle, &k.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let body_str = format!(
|
||||
"{}:{}:{}",
|
||||
PREPARE_MSIG, orid, &prepare_info.result.multisig_info
|
||||
|
@ -508,20 +592,24 @@ pub async fn send_prepare_info(orid: &String, contact: &String) {
|
|||
};
|
||||
let j_message: Json<Message> = utils::message_to_json(&message);
|
||||
monero::close_wallet(orid, &wallet_password).await;
|
||||
create(j_message, jwp, MessageType::Multisig).await;
|
||||
let str_jwp: String = bincode::deserialize(&jwp[..]).unwrap_or_default();
|
||||
create(j_message, str_jwp, MessageType::Multisig).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Enciphers and sends the output from the monero-rpc
|
||||
///
|
||||
/// `make_multisig_info` method.
|
||||
pub async fn send_make_info(orid: &String, contact: &String, info: Vec<String>) {
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
pub async fn send_make_info(orid: &String, contact: &String, info: Vec<String>) -> Result<(), NevekoError> {
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let wallet_name = String::from(orid);
|
||||
let wallet_password = String::new();
|
||||
monero::open_wallet(&wallet_name, &wallet_password).await;
|
||||
let make_info = monero::make_wallet(info).await;
|
||||
let k = format!("{}-{}", crate::FTS_JWP_DB_KEY, contact);
|
||||
let jwp = db::DatabaseEnvironment::read(&s.env, &s.handle, &k);
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let jwp = db::DatabaseEnvironment::read(&s.env, handle, &k.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let body_str = format!("{}:{}:{}", MAKE_MSIG, orid, &make_info.result.multisig_info);
|
||||
let message: Message = Message {
|
||||
body: body_str,
|
||||
|
@ -531,7 +619,9 @@ pub async fn send_make_info(orid: &String, contact: &String, info: Vec<String>)
|
|||
};
|
||||
let j_message: Json<Message> = utils::message_to_json(&message);
|
||||
monero::close_wallet(orid, &wallet_password).await;
|
||||
create(j_message, jwp, MessageType::Multisig).await;
|
||||
let str_jwp: String = bincode::deserialize(&jwp[..]).unwrap_or_default();
|
||||
create(j_message, str_jwp, MessageType::Multisig).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Enciphers and sends the output from the monero-rpc
|
||||
|
@ -542,14 +632,16 @@ pub async fn send_exchange_info(
|
|||
contact: &String,
|
||||
info: Vec<String>,
|
||||
kex_init: bool,
|
||||
) {
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
) -> Result<(), NevekoError> {
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let wallet_name = String::from(orid);
|
||||
let wallet_password = String::new();
|
||||
monero::open_wallet(&wallet_name, &wallet_password).await;
|
||||
let exchange_info = monero::exchange_multisig_keys(false, info, &wallet_password).await;
|
||||
let k = format!("{}-{}", crate::FTS_JWP_DB_KEY, contact);
|
||||
let jwp = db::DatabaseEnvironment::read(&s.env, &s.handle, &k);
|
||||
let jwp = db::DatabaseEnvironment::read(&s.env, handle, &k.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let mut body_str = format!(
|
||||
"{}:{}:{}",
|
||||
KEX_ONE_MSIG, orid, &exchange_info.result.multisig_info
|
||||
|
@ -568,20 +660,24 @@ pub async fn send_exchange_info(
|
|||
};
|
||||
let j_message: Json<Message> = utils::message_to_json(&message);
|
||||
monero::close_wallet(orid, &wallet_password).await;
|
||||
create(j_message, jwp, MessageType::Multisig).await;
|
||||
let str_jwp: String = bincode::deserialize(&jwp[..]).unwrap_or_default();
|
||||
create(j_message, str_jwp, MessageType::Multisig).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Enciphers and sends the output from the monero-rpc
|
||||
///
|
||||
/// `export_multisig_info` method.
|
||||
pub async fn send_export_info(orid: &String, contact: &String) {
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
pub async fn send_export_info(orid: &String, contact: &String) -> Result<(), NevekoError> {
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let wallet_name = String::from(orid);
|
||||
let wallet_password = String::new();
|
||||
monero::open_wallet(&wallet_name, &wallet_password).await;
|
||||
let exchange_info = monero::export_multisig_info().await;
|
||||
let k = format!("{}-{}", crate::FTS_JWP_DB_KEY, contact);
|
||||
let jwp = db::DatabaseEnvironment::read(&s.env, &s.handle, &k);
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let jwp = db::DatabaseEnvironment::read(&s.env, handle, &k.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let body_str = format!("{}:{}:{}", EXPORT_MSIG, orid, &exchange_info.result.info);
|
||||
let message: Message = Message {
|
||||
body: body_str,
|
||||
|
@ -591,7 +687,9 @@ pub async fn send_export_info(orid: &String, contact: &String) {
|
|||
};
|
||||
let j_message: Json<Message> = utils::message_to_json(&message);
|
||||
monero::close_wallet(orid, &wallet_password).await;
|
||||
create(j_message, jwp, MessageType::Multisig).await;
|
||||
let str_jwp: String = bincode::deserialize(&jwp[..]).unwrap_or_default();
|
||||
create(j_message, str_jwp, MessageType::Multisig).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// The customer or vendor (dispute only) needs to export
|
||||
|
@ -599,7 +697,7 @@ pub async fn send_export_info(orid: &String, contact: &String) {
|
|||
/// multisig info after funding. Once the info is imported
|
||||
///
|
||||
/// successfully the order needs to be updated to `MultisigComplete`.
|
||||
pub async fn send_import_info(orid: &String, info: &Vec<String>) {
|
||||
pub async fn send_import_info(orid: &String, info: &Vec<String>) -> Result<(), NevekoError> {
|
||||
let wallet_name = String::from(orid);
|
||||
let wallet_password = String::new();
|
||||
monero::open_wallet(&wallet_name, &wallet_password).await;
|
||||
|
@ -607,14 +705,15 @@ pub async fn send_import_info(orid: &String, info: &Vec<String>) {
|
|||
monero::close_wallet(orid, &wallet_password).await;
|
||||
if pre_import.result.n_outputs == 0 {
|
||||
error!("unable to import multisig info for order: {}", orid);
|
||||
return;
|
||||
return Err(NevekoError::Database(MdbError::Panic))?;
|
||||
}
|
||||
let mut old_order = order::find(orid);
|
||||
let mut old_order = order::find(orid)?;
|
||||
let status = order::StatusType::MulitsigComplete.value();
|
||||
old_order.status = String::from(&status);
|
||||
let j_old_order = Json(old_order);
|
||||
order::modify(j_old_order);
|
||||
order::modify(j_old_order)?;
|
||||
debug!("order: {} updated to: {}", orid, status);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Customer begins multisig orchestration by requesting the prepare info
|
||||
|
@ -690,10 +789,12 @@ pub async fn d_trigger_msig_info(
|
|||
mod tests {
|
||||
use super::*;
|
||||
|
||||
async fn cleanup(k: &String) {
|
||||
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
|
||||
let s = db::DatabaseEnvironment::async_open().await;
|
||||
db::DatabaseEnvironment::async_delete(&s.env, &s.handle, k).await;
|
||||
fn cleanup(k: &String) -> Result<(), NevekoError> {
|
||||
let s = db::DatabaseEnvironment::open()
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let _ = db::DatabaseEnvironment::delete(&s.env, &s.handle, k.as_bytes())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -721,24 +822,18 @@ mod tests {
|
|||
#[test]
|
||||
fn find_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 body: String = String::from("test body");
|
||||
let expected_message = Message {
|
||||
body: body,
|
||||
..Default::default()
|
||||
};
|
||||
let k = "test-key";
|
||||
tokio::spawn(async move {
|
||||
let s = db::DatabaseEnvironment::async_open().await;
|
||||
db::DatabaseEnvironment::async_write(&s.env, &s.handle, k, &Message::to_db(&expected_message))
|
||||
.await;
|
||||
let actual_message: Message = find(&String::from(k));
|
||||
assert_eq!(expected_message.body, actual_message.body);
|
||||
cleanup(&String::from(k)).await;
|
||||
});
|
||||
Runtime::shutdown_background(rt);
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let message = bincode::serialize(&new_message).unwrap_or_default();
|
||||
db::write_chunks(&s.env, &s.handle, k, &message);
|
||||
let actual_message: Message = find(&String::from(k));
|
||||
assert_eq!(expected_message.body, actual_message.body);
|
||||
cleanup(&String::from(k));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -5,7 +5,7 @@ use std::error::Error;
|
|||
use crate::{
|
||||
contact, db, error::NevekoError, i2p, models::*, monero, neveko25519, order, product, reqres, utils
|
||||
};
|
||||
use kn0sys_lmdb_rs::MdbError;
|
||||
use kn0sys_lmdb_rs::MdbError::{self};
|
||||
use log::{
|
||||
debug,
|
||||
error,
|
||||
|
@ -34,7 +34,7 @@ impl StatusType {
|
|||
}
|
||||
|
||||
/// Create a intial order
|
||||
pub async fn create(j_order: Json<reqres::OrderRequest>) -> Result<Order, MdbError> {
|
||||
pub async fn create(j_order: Json<reqres::OrderRequest>) -> Result<Order, NevekoError> {
|
||||
info!("creating order");
|
||||
let wallet_name = String::from(crate::APP_NAME);
|
||||
let wallet_password =
|
||||
|
@ -62,46 +62,62 @@ pub async fn create(j_order: Json<reqres::OrderRequest>) -> Result<Order, MdbErr
|
|||
if !m_wallet {
|
||||
error!("error creating msig wallet for order {}", &orid);
|
||||
monero::close_wallet(&orid, &wallet_password).await;
|
||||
return Err(MdbError::NotFound);
|
||||
return Err(NevekoError::Order);
|
||||
}
|
||||
monero::close_wallet(&orid, &order_wallet_password).await;
|
||||
debug!("insert order: {:?}", &new_order);
|
||||
let s = db::DatabaseEnvironment::open()?;
|
||||
let s = db::DatabaseEnvironment::open()
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
// inject adjudicator separately, modifying the order model is mendokusai
|
||||
let adjudicator_k = format!("{}-{}", crate::ADJUDICATOR_DB_KEY, &orid);
|
||||
db::write_chunks(&s.env, &s.handle?, adjudicator_k.as_bytes(), j_order.adjudicator.as_bytes());
|
||||
db::write_chunks(&s.env, handle, adjudicator_k.as_bytes(), j_order.adjudicator.as_bytes())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let k = &new_order.orid;
|
||||
let s = db::DatabaseEnvironment::open()?;
|
||||
let s = db::DatabaseEnvironment::open()
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let order = bincode::serialize(&new_order).unwrap_or_default();
|
||||
db::write_chunks(&s.env, &s.handle?, k.as_bytes(), &order);
|
||||
db::write_chunks(&s.env, handle, k.as_bytes(), &order)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
// in order to retrieve all orders, write keys to with ol
|
||||
let list_key = crate::ORDER_LIST_DB_KEY;
|
||||
let s = db::DatabaseEnvironment::open()?;
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &list_key.as_bytes().to_vec())?;
|
||||
let s = db::DatabaseEnvironment::open()
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let r = db::DatabaseEnvironment::read(&s.env, handle, &list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if r.is_empty() {
|
||||
debug!("creating order index");
|
||||
}
|
||||
let old: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
let order_list = [old, String::from(&orid)].join(",");
|
||||
debug!("writing order index {} for id: {}", order_list, list_key);
|
||||
let s = db::DatabaseEnvironment::open()?;
|
||||
db::write_chunks(&s.env, &s.handle?, list_key.as_bytes(), &order_list.as_bytes());
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
db::write_chunks(&s.env, handle, list_key.as_bytes(), &order_list.as_bytes())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
Ok(new_order)
|
||||
}
|
||||
|
||||
/// Backup order for customer
|
||||
pub fn backup(order: &Order) -> Result<(), MdbError> {
|
||||
pub fn backup(order: &Order) -> Result<(), NevekoError> {
|
||||
info!("creating backup of order: {}", order.orid);
|
||||
let s = db::DatabaseEnvironment::open()?;
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let k = &order.orid;
|
||||
db::DatabaseEnvironment::delete(&s.env, &s.handle?, k.as_bytes());
|
||||
let s = db::DatabaseEnvironment::open()?;
|
||||
db::DatabaseEnvironment::delete(&s.env, handle, k.as_bytes())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let order_to_db = bincode::serialize(&order).unwrap_or_default();
|
||||
db::write_chunks(&s.env, &s.handle?, k.as_bytes(), &order_to_db);
|
||||
db::write_chunks(&s.env, handle, k.as_bytes(), &order_to_db)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
// in order to retrieve all orders, write keys to with col
|
||||
let list_key = crate::CUSTOMER_ORDER_LIST_DB_KEY;
|
||||
let s = db::DatabaseEnvironment::open()?;
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &list_key.as_bytes().to_vec())?;
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let r = db::DatabaseEnvironment::read(&s.env, handle, &list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if r.is_empty() {
|
||||
debug!("creating customer order index");
|
||||
}
|
||||
|
@ -112,29 +128,37 @@ pub fn backup(order: &Order) -> Result<(), MdbError> {
|
|||
order_list = d_r;
|
||||
}
|
||||
debug!("writing order index {} for id: {}", order_list, list_key);
|
||||
let s = db::DatabaseEnvironment::open()?;
|
||||
db::write_chunks(&s.env, &s.handle?, list_key.as_bytes(), order_list.as_bytes());
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
db::write_chunks(&s.env, handle, list_key.as_bytes(), order_list.as_bytes())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Lookup order
|
||||
pub fn find(oid: &String) -> Result<Order, MdbError> {
|
||||
pub fn find(oid: &String) -> Result<Order, NevekoError> {
|
||||
info!("find order: {}", &oid);
|
||||
let s = db::DatabaseEnvironment::open()?;
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &oid.as_bytes().to_vec())?;
|
||||
let s = db::DatabaseEnvironment::open()
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let r = db::DatabaseEnvironment::read(&s.env, handle, &oid.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if r.is_empty() {
|
||||
error!("order not found");
|
||||
return Err(MdbError::NotFound);
|
||||
return Err(NevekoError::Database(MdbError::NotFound));
|
||||
}
|
||||
let result: Order = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// Lookup all orders from admin server
|
||||
pub fn find_all() -> Result<Vec<Order>, MdbError> {
|
||||
let i_s = db::DatabaseEnvironment::open()?;
|
||||
pub fn find_all() -> Result<Vec<Order>, NevekoError> {
|
||||
let s = db::DatabaseEnvironment::open()
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let i_list_key = crate::ORDER_LIST_DB_KEY;
|
||||
let i_r = db::DatabaseEnvironment::read(&i_s.env, &i_s.handle?, &i_list_key.as_bytes().to_vec())?;
|
||||
let i_r = db::DatabaseEnvironment::read(&s.env, handle, &i_list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if i_r.is_empty() {
|
||||
error!("order index not found");
|
||||
}
|
||||
|
@ -152,10 +176,13 @@ pub fn find_all() -> Result<Vec<Order>, MdbError> {
|
|||
}
|
||||
|
||||
/// Lookup all orders that customer has saved from gui
|
||||
pub fn find_all_backup() -> Result<Vec<Order>, MdbError> {
|
||||
let i_s = db::DatabaseEnvironment::open()?;
|
||||
pub fn find_all_backup() -> Result<Vec<Order>, NevekoError> {
|
||||
let i_s = db::DatabaseEnvironment::open()
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &i_s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let i_list_key = crate::CUSTOMER_ORDER_LIST_DB_KEY;
|
||||
let i_r = db::DatabaseEnvironment::read(&i_s.env, &i_s.handle?, &i_list_key.as_bytes().to_vec())?;
|
||||
let i_r = db::DatabaseEnvironment::read(&i_s.env, handle, &i_list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if i_r.is_empty() {
|
||||
error!("customer order index not found");
|
||||
}
|
||||
|
@ -176,11 +203,14 @@ pub fn find_all_backup() -> Result<Vec<Order>, MdbError> {
|
|||
}
|
||||
|
||||
/// Lookup all orders for customer
|
||||
pub async fn find_all_customer_orders(cid: String) -> Result<Vec<Order>, MdbError> {
|
||||
pub async fn find_all_customer_orders(cid: String) -> Result<Vec<Order>, NevekoError> {
|
||||
info!("lookup orders for customer: {}", &cid);
|
||||
let i_s = db::DatabaseEnvironment::open()?;
|
||||
let i_s = db::DatabaseEnvironment::open()
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &i_s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let i_list_key = crate::ORDER_LIST_DB_KEY;
|
||||
let i_r = db::DatabaseEnvironment::read(&i_s.env, &i_s.handle?, &i_list_key.as_bytes().to_vec())?;
|
||||
let i_r = db::DatabaseEnvironment::read(&i_s.env, handle, &i_list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if i_r.is_empty() {
|
||||
error!("order index not found");
|
||||
}
|
||||
|
@ -198,11 +228,14 @@ pub async fn find_all_customer_orders(cid: String) -> Result<Vec<Order>, MdbErro
|
|||
}
|
||||
|
||||
/// Lookup all orders for vendor
|
||||
pub fn find_all_vendor_orders() -> Result<Vec<Order>, MdbError> {
|
||||
pub fn find_all_vendor_orders() -> Result<Vec<Order>, NevekoError> {
|
||||
info!("lookup orders for vendor");
|
||||
let i_s = db::DatabaseEnvironment::open()?;
|
||||
let i_s = db::DatabaseEnvironment::open()
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &i_s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let i_list_key = crate::ORDER_LIST_DB_KEY;
|
||||
let i_r = db::DatabaseEnvironment::read(&i_s.env, &i_s.handle?, &i_list_key.as_bytes().to_vec())?;
|
||||
let i_r = db::DatabaseEnvironment::read(&i_s.env, handle, &i_list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if i_r.is_empty() {
|
||||
error!("order index not found");
|
||||
}
|
||||
|
@ -226,19 +259,25 @@ pub fn find_all_vendor_orders() -> Result<Vec<Order>, MdbError> {
|
|||
}
|
||||
|
||||
/// Modify order from admin server
|
||||
pub fn modify(o: Json<Order>) -> Result<Order, MdbError> {
|
||||
pub fn modify(o: Json<Order>) -> Result<Order, NevekoError> {
|
||||
info!("modify order: {}", &o.orid);
|
||||
let f_order: Order = find(&o.orid)?;
|
||||
if f_order.orid.is_empty() {
|
||||
error!("order not found");
|
||||
return Err(MdbError::NotFound);
|
||||
return Err(NevekoError::Database(MdbError::NotFound));
|
||||
}
|
||||
let u_order = Order::update(String::from(&f_order.orid), &o);
|
||||
let s = db::DatabaseEnvironment::open()?;
|
||||
db::DatabaseEnvironment::delete(&s.env, &s.handle?, &u_order.orid.as_bytes());
|
||||
let s = db::DatabaseEnvironment::open()
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let _ = db::DatabaseEnvironment::delete(&s.env, handle, &u_order.orid.as_bytes())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let v = bincode::serialize(&u_order).unwrap_or_default();
|
||||
let s = db::DatabaseEnvironment::open()?;
|
||||
db::write_chunks(&s.env, &s.handle?, &u_order.orid.as_bytes(), &v);
|
||||
let s = db::DatabaseEnvironment::open()
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let _ = db::write_chunks(&s.env, handle, &u_order.orid.as_bytes(), &v)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
Ok(u_order)
|
||||
}
|
||||
|
||||
|
@ -325,7 +364,7 @@ pub async fn cancel_order(orid: &String, signature: &String) -> Result<Order, Ne
|
|||
}
|
||||
// update the order status and send to customer
|
||||
m_order.status = order::StatusType::Cancelled.value();
|
||||
order::modify(Json(m_order));
|
||||
order::modify(Json(m_order))?;
|
||||
order::find(orid).map_err(|_| NevekoError::Order)
|
||||
}
|
||||
|
||||
|
@ -356,7 +395,7 @@ pub async fn validate_order_for_ship(orid: &String) -> Result<reqres::FinalizeOr
|
|||
&& r_balance.result.blocks_to_unlock < monero::LockTimeLimit::Blocks.value();
|
||||
if ready_to_ship {
|
||||
j_order.status = StatusType::Shipped.value();
|
||||
order::modify(Json(j_order));
|
||||
order::modify(Json(j_order))?;
|
||||
}
|
||||
let d_info: String = bincode::deserialize(&delivery_info[..]).unwrap_or_default();
|
||||
let e_delivery_info: String = neveko25519::cipher(
|
||||
|
@ -453,8 +492,9 @@ pub async fn upload_delivery_info(
|
|||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let k = String::from(crate::DELIVERY_INFO_DB_KEY);
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
db::write_chunks(&s.env, handle, k.as_bytes(), delivery_info.as_bytes());
|
||||
modify(Json(m_order));
|
||||
db::write_chunks(&s.env, handle, k.as_bytes(), delivery_info.as_bytes())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
modify(Json(m_order))?;
|
||||
// trigger nasr, this will cause the customer's neveko instance to request the
|
||||
// txset
|
||||
let i2p_address = i2p::get_destination(None);
|
||||
|
@ -520,7 +560,7 @@ pub async fn finalize_order(orid: &String) -> Result< reqres::FinalizeOrderRespo
|
|||
}
|
||||
monero::close_wallet(orid, &wallet_password).await;
|
||||
m_order.status = order::StatusType::Delivered.value();
|
||||
order::modify(Json(m_order));
|
||||
order::modify(Json(m_order))?;
|
||||
Ok(
|
||||
reqres::FinalizeOrderResponse {
|
||||
vendor_update_success: true,
|
||||
|
@ -584,7 +624,7 @@ pub async fn trigger_finalize_request(
|
|||
let unwrap: reqres::FinalizeOrderResponse = finalize.unwrap();
|
||||
let mut m_order: Order = order::find(orid).map_err(|_| NevekoError::Order)?;
|
||||
m_order.status = order::StatusType::Delivered.value();
|
||||
backup(&m_order);
|
||||
backup(&m_order)?;
|
||||
Ok(unwrap)
|
||||
}
|
||||
|
||||
|
@ -595,7 +635,7 @@ pub async fn d_trigger_finalize_request(
|
|||
) -> Result<reqres::FinalizeOrderResponse, NevekoError> {
|
||||
// ugh, sorry seems we need to get jwp for vendor from fts cache
|
||||
// get jwp from db
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::NotFound))?;
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let k = format!("{}-{}", crate::FTS_JWP_DB_KEY, &contact);
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let jwp = db::DatabaseEnvironment::read(&s.env, handle, &k.as_bytes().to_vec())
|
||||
|
@ -718,7 +758,11 @@ pub async fn transmit_sor_request(
|
|||
/// A decomposition trigger for the shipping request so that the logic
|
||||
///
|
||||
/// can be executed from the gui.
|
||||
pub async fn trigger_ship_request(contact: &String, jwp: &String, orid: &String) -> Order {
|
||||
pub async fn trigger_ship_request(
|
||||
contact: &String,
|
||||
jwp: &String,
|
||||
orid: &String
|
||||
) -> Result<Order, NevekoError> {
|
||||
info!("executing trigger_ship_request");
|
||||
let data = String::from(orid);
|
||||
let wallet_password =
|
||||
|
@ -730,17 +774,21 @@ pub async fn trigger_ship_request(contact: &String, jwp: &String, orid: &String)
|
|||
// cache order request to db
|
||||
if order.is_err() {
|
||||
log::error!("failed to trigger shipping request");
|
||||
return Default::default();
|
||||
return Err(NevekoError::Order);
|
||||
}
|
||||
let unwrap_order: Order = order.unwrap();
|
||||
backup(&unwrap_order);
|
||||
unwrap_order
|
||||
backup(&unwrap_order)?;
|
||||
Ok(unwrap_order)
|
||||
}
|
||||
|
||||
/// A post-decomposition trigger for the cancel request so that the logic
|
||||
///
|
||||
/// can be executed from the gui.
|
||||
pub async fn trigger_cancel_request(contact: &String, jwp: &String, orid: &String) -> Order {
|
||||
pub async fn trigger_cancel_request(
|
||||
contact: &String,
|
||||
jwp: &String,
|
||||
orid: &String
|
||||
) -> Result<Order, NevekoError> {
|
||||
info!("executing trigger_cancel_request");
|
||||
let data = String::from(orid);
|
||||
let wallet_password =
|
||||
|
@ -752,11 +800,11 @@ pub async fn trigger_cancel_request(contact: &String, jwp: &String, orid: &Strin
|
|||
// cache order request to db
|
||||
if order.is_err() {
|
||||
log::error!("failed to trigger cancel request");
|
||||
return Default::default();
|
||||
return Err(NevekoError::Order);
|
||||
}
|
||||
let unwrap_order: Order = order.unwrap();
|
||||
backup(&unwrap_order);
|
||||
unwrap_order
|
||||
backup(&unwrap_order)?;
|
||||
Ok(unwrap_order)
|
||||
}
|
||||
|
||||
/// Decomposition trigger for the shipping request
|
||||
|
@ -772,7 +820,7 @@ pub async fn d_trigger_ship_request(contact: &String, orid: &String) -> Result<O
|
|||
info!("executing d_trigger_ship_request");
|
||||
// request shipment if the order status is MultisigComplete
|
||||
let str_jwp: String = bincode::deserialize(&jwp[..]).unwrap_or_default();
|
||||
let trigger = trigger_ship_request(contact, &str_jwp, orid).await;
|
||||
let trigger = trigger_ship_request(contact, &str_jwp, orid).await?;
|
||||
if trigger.status == order::StatusType::MulitsigComplete.value() {
|
||||
let ship_res = transmit_ship_request(contact, &str_jwp, orid).await;
|
||||
if ship_res.is_err() {
|
||||
|
@ -785,7 +833,8 @@ pub async fn d_trigger_ship_request(contact: &String, orid: &String) -> Result<O
|
|||
let s = db::DatabaseEnvironment::open()
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
db::write_chunks(&s.env, handle, key.as_bytes(), hex_delivery_info.as_bytes());
|
||||
db::write_chunks(&s.env, handle, key.as_bytes(), hex_delivery_info.as_bytes())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
}
|
||||
Ok(trigger)
|
||||
}
|
||||
|
@ -846,7 +895,7 @@ pub async fn d_trigger_cancel_request(contact: &String, orid: &String) -> Result
|
|||
let order: Order = order::find(orid).map_err(|_| NevekoError::Order)?;
|
||||
if order.status != order::StatusType::MulitsigComplete.value() {
|
||||
let str_jwp: String = bincode::deserialize(&jwp[..]).unwrap_or_default();
|
||||
let trigger = trigger_cancel_request(contact, &str_jwp, orid).await;
|
||||
let trigger = trigger_cancel_request(contact, &str_jwp, orid).await?;
|
||||
if trigger.status == order::StatusType::Cancelled.value() {
|
||||
return Ok(trigger);
|
||||
}
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
//! Marketplace products upload, modification, etc module
|
||||
|
||||
use crate::{
|
||||
db,
|
||||
models::*,
|
||||
utils,
|
||||
db, error::NevekoError, models::*, utils
|
||||
};
|
||||
use kn0sys_lmdb_rs::MdbError;
|
||||
use log::{
|
||||
|
@ -15,11 +13,11 @@ use rocket::serde::json::Json;
|
|||
use std::error::Error;
|
||||
|
||||
/// Create a new product
|
||||
pub fn create(d: Json<Product>) -> Result<Product, MdbError> {
|
||||
pub fn create(d: Json<Product>) -> Result<Product, NevekoError> {
|
||||
let pid: String = format!("{}{}", crate::PRODUCT_DB_KEY, utils::generate_rnd());
|
||||
if !validate_product(&d) {
|
||||
error!("invalid product");
|
||||
return Err(MdbError::NotFound);
|
||||
return Err(NevekoError::Database(MdbError::NotFound));
|
||||
}
|
||||
let new_product = Product {
|
||||
pid: String::from(&pid),
|
||||
|
@ -31,14 +29,18 @@ pub fn create(d: Json<Product>) -> Result<Product, MdbError> {
|
|||
qty: d.qty,
|
||||
};
|
||||
debug!("insert product: {:?}", &new_product);
|
||||
let s = db::DatabaseEnvironment::open()?;
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let k = &new_product.pid;
|
||||
let product = bincode::serialize(&new_product).unwrap_or_default();
|
||||
db::write_chunks(&s.env, &s.handle?, k.as_bytes(), &product);
|
||||
db::write_chunks(&s.env, handle, k.as_bytes(), &product)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
// in order to retrieve all products, write keys to with pl
|
||||
let list_key = crate::PRODUCT_LIST_DB_KEY;
|
||||
let s = db::DatabaseEnvironment::open()?;
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &list_key.as_bytes().to_vec())?;
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let r = db::DatabaseEnvironment::read(&s.env, handle, &list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if r.is_empty() {
|
||||
debug!("creating product index");
|
||||
}
|
||||
|
@ -48,28 +50,34 @@ pub fn create(d: Json<Product>) -> Result<Product, MdbError> {
|
|||
"writing product index {} for id: {}",
|
||||
product_list, list_key
|
||||
);
|
||||
let s = db::DatabaseEnvironment::open()?;
|
||||
db::write_chunks(&s.env, &s.handle?, list_key.as_bytes(), product_list.as_bytes());
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
db::write_chunks(&s.env, handle, list_key.as_bytes(), product_list.as_bytes())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
Ok(new_product)
|
||||
}
|
||||
|
||||
/// Single Product lookup
|
||||
pub fn find(pid: &String) -> Result<Product, MdbError> {
|
||||
let s = db::DatabaseEnvironment::open()?;
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &pid.as_bytes().to_vec())?;
|
||||
pub fn find(pid: &String) -> Result<Product, NevekoError> {
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let r = db::DatabaseEnvironment::read(&s.env, handle, &pid.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if r.is_empty() {
|
||||
error!("product not found");
|
||||
return Err(MdbError::NotFound);
|
||||
return Err(NevekoError::Database(MdbError::NotFound));
|
||||
}
|
||||
let result: Product = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// Product lookup for all
|
||||
pub fn find_all() -> Result<Vec<Product>, MdbError> {
|
||||
let i_s = db::DatabaseEnvironment::open()?;
|
||||
pub fn find_all() -> Result<Vec<Product>, NevekoError> {
|
||||
let i_s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let i_list_key = crate::PRODUCT_LIST_DB_KEY;
|
||||
let i_r = db::DatabaseEnvironment::read(&i_s.env, &i_s.handle?, &i_list_key.as_bytes().to_vec())?;
|
||||
let handle = &i_s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let i_r = db::DatabaseEnvironment::read(&i_s.env, handle, &i_list_key.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if i_r.is_empty() {
|
||||
error!("product index not found");
|
||||
}
|
||||
|
@ -89,20 +97,23 @@ pub fn find_all() -> Result<Vec<Product>, MdbError> {
|
|||
}
|
||||
|
||||
/// Modify product
|
||||
pub fn modify(p: Json<Product>) -> Result<Product, MdbError> {
|
||||
pub fn modify(p: Json<Product>) -> Result<Product, NevekoError> {
|
||||
// TODO(c2m): don't allow modification to products with un-delivered orders
|
||||
info!("modify product: {}", &p.pid);
|
||||
let f_prod: Product = find(&p.pid)?;
|
||||
if f_prod.pid.is_empty() {
|
||||
error!("product not found");
|
||||
return Err(MdbError::NotFound);
|
||||
return Err(NevekoError::Database(MdbError::NotFound));
|
||||
}
|
||||
let u_prod = Product::update(f_prod, &p);
|
||||
let s = db::DatabaseEnvironment::open()?;
|
||||
db::DatabaseEnvironment::delete(&s.env, &s.handle?, u_prod.pid.as_bytes())?;
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let _ = db::DatabaseEnvironment::delete(&s.env, handle, u_prod.pid.as_bytes())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let product = bincode::serialize(&u_prod).unwrap_or_default();
|
||||
let s = db::DatabaseEnvironment::open()?;
|
||||
db::write_chunks(&s.env, &s.handle?, u_prod.pid.as_bytes(), &product);
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
db::write_chunks(&s.env, handle, u_prod.pid.as_bytes(), &product)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
Ok(u_prod)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
//! External authorization module via JWPs
|
||||
|
||||
use crate::{
|
||||
db,
|
||||
monero,
|
||||
reqres,
|
||||
utils,
|
||||
db, error::NevekoError, monero, reqres, utils
|
||||
};
|
||||
use kn0sys_lmdb_rs::MdbError;
|
||||
use log::{
|
||||
error,
|
||||
info,
|
||||
|
@ -125,9 +123,10 @@ pub async fn prove_payment(contact: String, txp: &TxProof) -> Result<reqres::Jwp
|
|||
|
||||
let s = db::DatabaseEnvironment::open()?;
|
||||
let k = format!("{}-{}", crate::FTS_JWP_DB_KEY, &contact);
|
||||
db::DatabaseEnvironment::delete(&s.env, &s.handle?, k.as_bytes())?;
|
||||
let _ = db::DatabaseEnvironment::delete(&s.env, &s.handle?, k.as_bytes())?;
|
||||
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())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
Ok(r)
|
||||
}
|
||||
_ => Ok(Default::default()),
|
||||
|
|
|
@ -812,7 +812,7 @@ pub struct XmrRpcQueryKeyResponse {
|
|||
// END XMR Structs
|
||||
|
||||
/// Container for the message decipher
|
||||
#[derive(Debug, Default, Deserialize)]
|
||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||
#[serde(crate = "rocket::serde")]
|
||||
pub struct DecipheredMessageBody {
|
||||
pub mid: String,
|
||||
|
|
|
@ -1,16 +1,7 @@
|
|||
//! Generic functions for startup and convenience
|
||||
|
||||
use crate::{
|
||||
args,
|
||||
contact,
|
||||
db,
|
||||
dispute,
|
||||
i2p,
|
||||
message,
|
||||
models,
|
||||
monero,
|
||||
neveko25519,
|
||||
reqres,
|
||||
args, contact, db, dispute, error::NevekoError, i2p, message, models, monero, neveko25519, reqres
|
||||
};
|
||||
use clap::Parser;
|
||||
use kn0sys_lmdb_rs::MdbError;
|
||||
|
@ -60,21 +51,6 @@ impl Default for ContactStatus {
|
|||
}
|
||||
}
|
||||
|
||||
/// Enum for selecting hash validation
|
||||
#[derive(PartialEq)]
|
||||
enum ExternalSoftware {
|
||||
I2PZero,
|
||||
XMR,
|
||||
}
|
||||
|
||||
/// Handles the state for the installation manager popup
|
||||
#[derive(Default)]
|
||||
pub struct Installations {
|
||||
pub xmr: bool,
|
||||
pub i2p_zero: bool,
|
||||
}
|
||||
|
||||
|
||||
/// Handles the state for the connection manager popup
|
||||
pub struct Connections {
|
||||
pub blockchain_dir: String,
|
||||
|
@ -406,7 +382,7 @@ async fn gen_app_wallet(password: &String) {
|
|||
}
|
||||
|
||||
/// Secret keys for signing internal/external auth tokens
|
||||
fn gen_signing_keys() -> Result<(), MdbError> {
|
||||
fn gen_signing_keys() -> Result<(), NevekoError> {
|
||||
info!("generating signing keys");
|
||||
let jwp = get_jwp_secret_key()?;
|
||||
let jwt = get_jwt_secret_key()?;
|
||||
|
@ -414,14 +390,18 @@ fn gen_signing_keys() -> Result<(), MdbError> {
|
|||
if jwp.is_empty() {
|
||||
let mut data = [0u8; 32];
|
||||
rand::thread_rng().fill_bytes(&mut data);
|
||||
let s = db::DatabaseEnvironment::open()?;
|
||||
db::write_chunks(&s.env, &s.handle?, crate::NEVEKO_JWP_SECRET_KEY.as_bytes(), &data);
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
db::write_chunks(&s.env, handle, crate::NEVEKO_JWP_SECRET_KEY.as_bytes(), &data)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
}
|
||||
if jwt.is_empty() {
|
||||
let mut data = [0u8; 32];
|
||||
rand::thread_rng().fill_bytes(&mut data);
|
||||
let s = db::DatabaseEnvironment::open()?;
|
||||
db::write_chunks(&s.env, &s.handle?, crate::NEVEKO_JWT_SECRET_KEY.as_bytes(), &data);
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
db::write_chunks(&s.env, handle, crate::NEVEKO_JWT_SECRET_KEY.as_bytes(), &data)
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -429,75 +409,84 @@ fn gen_signing_keys() -> Result<(), MdbError> {
|
|||
/// TODO(c2m): add a button to gui to call this
|
||||
///
|
||||
/// dont' forget to generate new keys as well
|
||||
pub fn revoke_signing_keys() -> Result<(), MdbError> {
|
||||
|
||||
let s = db::DatabaseEnvironment::open()?;
|
||||
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());
|
||||
pub fn revoke_signing_keys() -> Result<(), NevekoError> {
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
db::DatabaseEnvironment::delete(&s.env, handle, crate::NEVEKO_JWT_SECRET_KEY.as_bytes())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
db::DatabaseEnvironment::delete(&s.env, handle, crate::NEVEKO_JWP_SECRET_KEY.as_bytes())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
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.as_bytes().to_vec())?;
|
||||
pub fn get_jwt_secret_key() -> Result<String, NevekoError> {
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let r = db::DatabaseEnvironment::read(&s.env, handle, &crate::NEVEKO_JWT_SECRET_KEY.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if r.is_empty() {
|
||||
error!("JWT key not found");
|
||||
return Err(MdbError::NotFound);
|
||||
return Err(NevekoError::Database(MdbError::Panic));
|
||||
}
|
||||
let result: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub fn get_jwp_secret_key() -> Result<String, MdbError> {
|
||||
pub fn get_jwp_secret_key() -> Result<String, NevekoError> {
|
||||
|
||||
let s = db::DatabaseEnvironment::open()?;
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &crate::NEVEKO_JWP_SECRET_KEY.as_bytes().to_vec())?;
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let r = db::DatabaseEnvironment::read(&s.env, handle, &crate::NEVEKO_JWP_SECRET_KEY.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if r.is_empty() {
|
||||
error!("JWP key not found");
|
||||
return Err(MdbError::NotFound);
|
||||
return Err(NevekoError::Database(MdbError::NotFound));
|
||||
}
|
||||
let result: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// Returns the hex encoded neveko message public key from LMDB
|
||||
pub fn get_nmpk() -> Result<String, MdbError> {
|
||||
let s = db::DatabaseEnvironment::open()?;
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &crate::NEVEKO_NMPK.as_bytes().to_vec())?;
|
||||
pub fn get_nmpk() -> Result<String, NevekoError> {
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let r = db::DatabaseEnvironment::read(&s.env, handle, &crate::NEVEKO_NMPK.as_bytes().to_vec())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if r.is_empty() {
|
||||
error!("neveko message public key not found");
|
||||
return Err(MdbError::NotFound);
|
||||
return Err(NevekoError::Database(MdbError::Panic));
|
||||
}
|
||||
let result: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
async fn generate_nmpk() -> Result<(), MdbError> {
|
||||
async fn generate_nmpk() -> Result<(), NevekoError> {
|
||||
info!("generating neveko message public key");
|
||||
let nmpk: String = get_nmpk()?;
|
||||
// send to db
|
||||
let s = db::DatabaseEnvironment::open()?;
|
||||
let s = db::DatabaseEnvironment::open().map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
if nmpk.is_empty() {
|
||||
let nmk: neveko25519::NevekoMessageKeys = neveko25519::generate_neveko_message_keys().await;
|
||||
db::write_chunks(&s.env, &s.handle?, crate::NEVEKO_NMPK.as_bytes(), nmk.hex_nmpk.as_bytes());
|
||||
db::write_chunks(&s.env, handle, crate::NEVEKO_NMPK.as_bytes(), nmk.hex_nmpk.as_bytes())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Put all app pre-checks here
|
||||
pub async fn start_up() {
|
||||
pub async fn start_up() -> Result<(), NevekoError> {
|
||||
info!("neveko is starting up");
|
||||
warn!("monero multisig is experimental and usage of neveko may lead to loss of funds");
|
||||
let args = args::Args::parse();
|
||||
if args.clear_fts {
|
||||
clear_fts();
|
||||
clear_fts()?;
|
||||
}
|
||||
if args.clear_disputes {
|
||||
clear_disputes();
|
||||
clear_disputes()?;
|
||||
}
|
||||
gen_signing_keys();
|
||||
gen_signing_keys()?;
|
||||
if !is_using_remote_node() {
|
||||
monero::start_daemon();
|
||||
}
|
||||
|
@ -518,7 +507,7 @@ pub async fn start_up() {
|
|||
wallet_password = read_password().unwrap();
|
||||
std::env::set_var(crate::MONERO_WALLET_PASSWORD, &wallet_password);
|
||||
}
|
||||
generate_nmpk().await;
|
||||
generate_nmpk().await?;
|
||||
let env: String = get_release_env().value();
|
||||
if !args.i2p_advanced {
|
||||
i2p::start().await;
|
||||
|
@ -527,11 +516,12 @@ pub async fn start_up() {
|
|||
// start async background tasks here
|
||||
{
|
||||
tokio::spawn(async {
|
||||
message::retry_fts().await;
|
||||
dispute::settle_dispute().await;
|
||||
let _ = message::retry_fts().await;
|
||||
let _ = dispute::settle_dispute().await;
|
||||
});
|
||||
}
|
||||
info!("{} - neveko is online", env);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// TODO(?): get rid of this after implementing monero bindings
|
||||
|
@ -567,30 +557,36 @@ pub fn kill_child_processes(cm: bool) {
|
|||
/// We can restart fts from since it gets terminated when empty
|
||||
pub fn restart_retry_fts() {
|
||||
tokio::spawn(async move {
|
||||
message::retry_fts().await;
|
||||
let _ = message::retry_fts().await;
|
||||
});
|
||||
}
|
||||
|
||||
/// We can restart dispute auto-settle from since it gets terminated when empty
|
||||
pub fn restart_dispute_auto_settle() {
|
||||
tokio::spawn(async move {
|
||||
dispute::settle_dispute().await;
|
||||
let _ = dispute::settle_dispute().await;
|
||||
});
|
||||
}
|
||||
|
||||
/// Called on app startup if `--clear-fts` flag is passed.
|
||||
fn clear_fts() -> Result<(), MdbError> {
|
||||
fn clear_fts() -> Result<(), NevekoError> {
|
||||
info!("clear fts");
|
||||
let s = db::DatabaseEnvironment::open()?;
|
||||
db::DatabaseEnvironment::delete(&s.env, &s.handle?, crate::FTS_DB_KEY.as_bytes());
|
||||
let s = db::DatabaseEnvironment::open()
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
db::DatabaseEnvironment::delete(&s.env, handle, crate::FTS_DB_KEY.as_bytes())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Called on app startup if `--clear-dispute` flag is passed.
|
||||
fn clear_disputes() -> Result<(), MdbError> {
|
||||
fn clear_disputes() -> Result<(), NevekoError> {
|
||||
info!("clear_disputes");
|
||||
let s = db::DatabaseEnvironment::open()?;
|
||||
db::DatabaseEnvironment::delete(&s.env, &s.handle?, crate::DISPUTE_LIST_DB_KEY.as_bytes());
|
||||
let s = db::DatabaseEnvironment::open()
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
let handle = &s.handle.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
db::DatabaseEnvironment::delete(&s.env, handle, crate::DISPUTE_LIST_DB_KEY.as_bytes())
|
||||
.map_err(|_| NevekoError::Database(MdbError::Panic))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -710,7 +706,7 @@ pub fn toggle_vendor_enabled() -> Result<bool, MdbError> {
|
|||
&s.handle?,
|
||||
contact::NEVEKO_VENDOR_ENABLED.as_bytes(),
|
||||
contact::NEVEKO_VENDOR_MODE_ON.as_bytes(),
|
||||
);
|
||||
)?;
|
||||
Ok(true)
|
||||
} else {
|
||||
info!("neveko vendor mode disabled");
|
||||
|
@ -720,7 +716,7 @@ pub fn toggle_vendor_enabled() -> Result<bool, MdbError> {
|
|||
&s.handle?,
|
||||
contact::NEVEKO_VENDOR_ENABLED.as_bytes(),
|
||||
contact::NEVEKO_VENDOR_MODE_OFF.as_bytes(),
|
||||
);
|
||||
)?;
|
||||
Ok(false)
|
||||
}
|
||||
}
|
||||
|
@ -736,7 +732,7 @@ pub fn search_gui_db(f: String, data: String) -> Result<String, MdbError> {
|
|||
pub fn write_gui_db(f: String, key: String, data: String) -> Result<(), MdbError> {
|
||||
let s = db::DatabaseEnvironment::open()?;
|
||||
let k = format!("{}-{}", f, key);
|
||||
db::write_chunks(&s.env, &s.handle?, k.as_bytes(), data.as_bytes());
|
||||
db::write_chunks(&s.env, &s.handle?, k.as_bytes(), data.as_bytes())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ wgpu = ["eframe/wgpu", "bytemuck"]
|
|||
|
||||
|
||||
[dependencies]
|
||||
bincode = "1.3.3"
|
||||
chrono = { version = "0.4", features = ["js-sys", "wasmbind"] }
|
||||
eframe = { version = "0.21.0", path = "./crates/eframe", default-features = false }
|
||||
egui = { version = "0.21.0", path = "./crates/egui", features = [
|
||||
|
|
|
@ -197,7 +197,7 @@ impl eframe::App for AddressBookApp {
|
|||
|
||||
// initial contact load
|
||||
if !self.contacts_init {
|
||||
self.contacts = contact::find_all();
|
||||
self.contacts = contact::find_all().unwrap_or_default();
|
||||
self.contacts_init = true;
|
||||
}
|
||||
|
||||
|
@ -347,9 +347,9 @@ impl eframe::App for AddressBookApp {
|
|||
&& self.status.jwp.is_empty();
|
||||
if !self.status.jwp.is_empty() || failed_to_prove {
|
||||
if ui.button("Clear stale JWP").clicked() {
|
||||
utils::clear_gui_db(String::from("gui-txp"), self.status.i2p.clone());
|
||||
utils::clear_gui_db(String::from("gui-jwp"), self.status.i2p.clone());
|
||||
utils::clear_gui_db(String::from("gui-exp"), self.status.i2p.clone());
|
||||
utils::clear_gui_db(String::from("gui-txp"), self.status.i2p.clone()).unwrap();
|
||||
utils::clear_gui_db(String::from("gui-jwp"), self.status.i2p.clone()).unwrap();
|
||||
utils::clear_gui_db(String::from("gui-exp"), self.status.i2p.clone()).unwrap();
|
||||
self.showing_status = false;
|
||||
}
|
||||
}
|
||||
|
@ -422,7 +422,7 @@ impl eframe::App for AddressBookApp {
|
|||
self.contact = String::new();
|
||||
self.is_adding = false;
|
||||
self.approve_contact = false;
|
||||
self.contacts = contact::find_all();
|
||||
self.contacts = contact::find_all().unwrap_or_default();
|
||||
for c in &self.contacts {
|
||||
ui.label(format!("{}", c.i2p_address));
|
||||
}
|
||||
|
@ -541,10 +541,11 @@ impl eframe::App for AddressBookApp {
|
|||
String::from(crate::GUI_NICK_DB_KEY),
|
||||
String::from(&c.i2p_address),
|
||||
);
|
||||
let nick = if nick_db.is_empty() {
|
||||
let u_nick = nick_db.unwrap_or_default();
|
||||
let nick = if u_nick.is_empty() {
|
||||
String::from("anon")
|
||||
} else {
|
||||
nick_db
|
||||
u_nick
|
||||
};
|
||||
self.status.nick = nick;
|
||||
self.status.i2p = String::from(&c.i2p_address);
|
||||
|
@ -552,16 +553,16 @@ impl eframe::App for AddressBookApp {
|
|||
self.status.txp = utils::search_gui_db(
|
||||
String::from(crate::GUI_TX_PROOF_DB_KEY),
|
||||
String::from(&c.i2p_address),
|
||||
);
|
||||
).unwrap_or_default();
|
||||
// get the jwp
|
||||
self.status.jwp = utils::search_gui_db(
|
||||
String::from(crate::GUI_JWP_DB_KEY),
|
||||
String::from(&c.i2p_address),
|
||||
);
|
||||
).unwrap_or_default();
|
||||
let r_exp = utils::search_gui_db(
|
||||
String::from(crate::GUI_EXP_DB_KEY),
|
||||
String::from(&c.i2p_address),
|
||||
);
|
||||
).unwrap_or_default();
|
||||
self.status.exp = r_exp;
|
||||
let expire = match self.status.exp.parse::<i64>() {
|
||||
Ok(n) => n,
|
||||
|
@ -622,8 +623,8 @@ fn send_create_contact_req(tx: Sender<models::Contact>, ctx: egui::Context, c: m
|
|||
log::debug!("async send_create_contact_req");
|
||||
tokio::spawn(async move {
|
||||
let j_contact = utils::contact_to_json(&c);
|
||||
let a_contact: models::Contact = contact::create(&j_contact).await;
|
||||
let _ = tx.send(a_contact);
|
||||
let a_contact = contact::create(&j_contact).await;
|
||||
let _ = tx.send(a_contact.unwrap_or_default());
|
||||
ctx.request_repaint();
|
||||
});
|
||||
}
|
||||
|
@ -662,9 +663,9 @@ fn send_payment_req(
|
|||
log::debug!("cleaning stale jwp values");
|
||||
tokio::spawn(async move {
|
||||
if !retry {
|
||||
utils::clear_gui_db(String::from("gui-txp"), String::from(&contact));
|
||||
utils::clear_gui_db(String::from("gui-jwp"), String::from(&contact));
|
||||
utils::clear_gui_db(String::from("gui-exp"), String::from(&contact));
|
||||
utils::clear_gui_db(String::from("gui-txp"), String::from(&contact)).unwrap();
|
||||
utils::clear_gui_db(String::from("gui-jwp"), String::from(&contact)).unwrap();
|
||||
utils::clear_gui_db(String::from("gui-exp"), String::from(&contact)).unwrap();
|
||||
let ptxp_address = String::from(&d.address);
|
||||
let ftxp_address = String::from(&d.address);
|
||||
log::debug!("sending {} piconero(s) to: {}", &d.amount, &d.address);
|
||||
|
@ -712,22 +713,22 @@ fn send_payment_req(
|
|||
String::from(crate::GUI_TX_PROOF_DB_KEY),
|
||||
String::from(&contact),
|
||||
String::from(&ftxp.signature),
|
||||
);
|
||||
).unwrap();
|
||||
utils::write_gui_db(
|
||||
String::from(crate::GUI_TX_HASH_DB_KEY),
|
||||
String::from(&contact),
|
||||
String::from(&ftxp.hash),
|
||||
);
|
||||
).unwrap();
|
||||
utils::write_gui_db(
|
||||
String::from(crate::GUI_TX_SIGNATURE_DB_KEY),
|
||||
String::from(&contact),
|
||||
String::from(&ftxp.signature),
|
||||
);
|
||||
).unwrap();
|
||||
utils::write_gui_db(
|
||||
String::from(crate::GUI_TX_SUBADDRESS_DB_KEY),
|
||||
String::from(&contact),
|
||||
String::from(&ftxp.subaddress),
|
||||
);
|
||||
).unwrap();
|
||||
log::debug!(
|
||||
"proving payment to {} for: {}",
|
||||
String::from(&contact),
|
||||
|
@ -739,7 +740,7 @@ fn send_payment_req(
|
|||
String::from(crate::GUI_JWP_DB_KEY),
|
||||
String::from(&contact),
|
||||
String::from(&result.jwp),
|
||||
);
|
||||
).unwrap();
|
||||
// this is just an estimate expiration but should suffice
|
||||
let seconds: i64 = expire as i64 * 2 * 60;
|
||||
let unix: i64 = chrono::offset::Utc::now().timestamp() + seconds;
|
||||
|
@ -747,7 +748,7 @@ fn send_payment_req(
|
|||
String::from(crate::GUI_EXP_DB_KEY),
|
||||
String::from(&contact),
|
||||
format!("{}", unix),
|
||||
);
|
||||
).unwrap();
|
||||
ctx.request_repaint();
|
||||
}
|
||||
_ => log::error!("failed to obtain jwp"),
|
||||
|
@ -758,9 +759,12 @@ fn send_payment_req(
|
|||
let k_hash = String::from(crate::GUI_TX_HASH_DB_KEY);
|
||||
let k_sig = String::from(crate::GUI_TX_SIGNATURE_DB_KEY);
|
||||
let k_subaddress = String::from(crate::GUI_TX_SUBADDRESS_DB_KEY);
|
||||
let hash = utils::search_gui_db(k_hash, String::from(&contact));
|
||||
let signature = utils::search_gui_db(k_sig, String::from(&contact));
|
||||
let subaddress = utils::search_gui_db(k_subaddress, String::from(&contact));
|
||||
let hash = utils::search_gui_db(k_hash, String::from(&contact))
|
||||
.unwrap_or_default();
|
||||
let signature = utils::search_gui_db(k_sig, String::from(&contact))
|
||||
.unwrap_or_default();
|
||||
let subaddress = utils::search_gui_db(k_subaddress, String::from(&contact))
|
||||
.unwrap_or_default();
|
||||
let ftxp: proof::TxProof = proof::TxProof {
|
||||
subaddress,
|
||||
confirmations: 0,
|
||||
|
@ -779,7 +783,7 @@ fn send_payment_req(
|
|||
String::from(crate::GUI_JWP_DB_KEY),
|
||||
String::from(&contact),
|
||||
String::from(&result.jwp),
|
||||
);
|
||||
).unwrap();
|
||||
ctx.request_repaint();
|
||||
}
|
||||
_ => log::error!("failed to obtain jwp"),
|
||||
|
@ -804,8 +808,9 @@ fn send_message_req(tx: Sender<bool>, ctx: egui::Context, body: String, to: Stri
|
|||
tokio::spawn(async move {
|
||||
let m_type = message::MessageType::Normal;
|
||||
let result = message::create(j_message, jwp, m_type).await;
|
||||
if !result.mid.is_empty() {
|
||||
log::info!("sent message: {}", result.mid);
|
||||
let u_res = result.unwrap_or_default();
|
||||
if !u_res.mid.is_empty() {
|
||||
log::info!("sent message: {}", u_res.mid);
|
||||
let _ = tx.send(true);
|
||||
ctx.request_repaint();
|
||||
}
|
||||
|
@ -814,12 +819,12 @@ fn send_message_req(tx: Sender<bool>, ctx: egui::Context, body: String, to: Stri
|
|||
|
||||
fn change_nick_req(contact: String, nick: String) {
|
||||
log::debug!("change nick");
|
||||
utils::clear_gui_db(String::from(crate::GUI_NICK_DB_KEY), String::from(&contact));
|
||||
utils::clear_gui_db(String::from(crate::GUI_NICK_DB_KEY), String::from(&contact)).unwrap();
|
||||
utils::write_gui_db(
|
||||
String::from(crate::GUI_NICK_DB_KEY),
|
||||
String::from(&contact),
|
||||
nick,
|
||||
);
|
||||
).unwrap();
|
||||
}
|
||||
|
||||
fn send_can_transfer_req(tx: Sender<bool>, ctx: egui::Context, invoice: u128) {
|
||||
|
|
|
@ -67,8 +67,6 @@ impl Default for HomeApp {
|
|||
fn default() -> Self {
|
||||
let blocks_fetched = 0;
|
||||
let connections = Default::default();
|
||||
let has_install_failed = false;
|
||||
let installations = Default::default();
|
||||
let is_core_running = false;
|
||||
let is_editing_connections = false;
|
||||
let is_init = true;
|
||||
|
@ -87,7 +85,6 @@ impl Default for HomeApp {
|
|||
let (wallet_height_tx, wallet_height_rx) = std::sync::mpsc::channel();
|
||||
let (can_refresh_tx, can_refresh_rx) = std::sync::mpsc::channel();
|
||||
let (i2p_status_tx, i2p_status_rx) = std::sync::mpsc::channel();
|
||||
let (installation_tx, installation_rx) = std::sync::mpsc::channel();
|
||||
let contents = std::fs::read("./assets/qr.png").unwrap_or(Vec::new());
|
||||
let s_xmr_rpc_ver = Default::default();
|
||||
let s_xmr_address = Default::default();
|
||||
|
@ -175,13 +172,6 @@ impl eframe::App for HomeApp {
|
|||
if let Ok(info) = self.xmrd_get_info_rx.try_recv() {
|
||||
self.s_xmrd_get_info = info;
|
||||
}
|
||||
if let Ok(install) = self.installation_rx.try_recv() {
|
||||
self.is_installing = !install;
|
||||
if !install && self.is_loading {
|
||||
self.has_install_failed = true
|
||||
}
|
||||
self.is_loading = false;
|
||||
}
|
||||
if let Ok(timeout) = self.core_timeout_rx.try_recv() {
|
||||
self.is_timeout = true;
|
||||
if timeout {
|
||||
|
@ -424,7 +414,7 @@ impl eframe::App for HomeApp {
|
|||
fn send_xmrd_get_info_req(tx: Sender<reqres::XmrDaemonGetInfoResponse>, ctx: egui::Context) {
|
||||
tokio::spawn(async move {
|
||||
let remote_var =
|
||||
std::env::var(neveko_core::GUI_REMOTE_NODE).unwrap_or(utils::empty_string());
|
||||
std::env::var(neveko_core::GUI_REMOTE_NODE).unwrap_or(String::new());
|
||||
if remote_var == String::from(neveko_core::GUI_SET_REMOTE_NODE) {
|
||||
let p_info = monero::p_get_info().await;
|
||||
let info = p_info.unwrap_or(Default::default());
|
||||
|
|
|
@ -62,13 +62,18 @@ impl eframe::App for LockScreenApp {
|
|||
self.lock_screen.credential.clone(),
|
||||
);
|
||||
// Get the credential hash from lmdb
|
||||
let s = db::DatabaseEnvironment::open(&utils::get_release_env().value()).unwrap();
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, CREDENTIAL_KEY);
|
||||
let s = db::DatabaseEnvironment::open().unwrap();
|
||||
let r = db::DatabaseEnvironment::read(
|
||||
&s.env,
|
||||
&s.handle.unwrap(),
|
||||
&CREDENTIAL_KEY.as_bytes().to_vec(),
|
||||
).unwrap();
|
||||
// hash the text entered and compare
|
||||
let mut hasher = Sha512::new();
|
||||
hasher.update(self.lock_screen.credential.clone());
|
||||
let result = hasher.finalize();
|
||||
let hex = hex::encode(&result[..]);
|
||||
let r: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
if hex == r {
|
||||
self.is_locked = false;
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ impl eframe::App for MailBoxApp {
|
|||
|
||||
// initial message load
|
||||
if !self.message_init {
|
||||
self.messages = message::find_all();
|
||||
self.messages = message::find_all().unwrap_or_default();
|
||||
self.message_init = true;
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,7 @@ impl eframe::App for MailBoxApp {
|
|||
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
if ui.button("Refresh").clicked() {
|
||||
self.messages = message::find_all();
|
||||
self.messages = message::find_all().unwrap_or_default();
|
||||
}
|
||||
ui.label("\n");
|
||||
use egui_extras::{
|
||||
|
@ -144,7 +144,7 @@ impl eframe::App for MailBoxApp {
|
|||
}
|
||||
}
|
||||
if ui.button("Delete").clicked() {
|
||||
message::delete(&m.mid);
|
||||
message::delete(&m.mid).unwrap();
|
||||
refresh_on_delete_req(
|
||||
self.refresh_on_delete_tx.clone(),
|
||||
ctx.clone(),
|
||||
|
@ -173,7 +173,7 @@ fn decipher_req(m: &Message, tx: Sender<String>, ctx: egui::Context) {
|
|||
let body: String = String::from(&m.body);
|
||||
tokio::spawn(async move {
|
||||
log::info!("async decipher_req");
|
||||
let contact = contact::find_by_i2p_address(&from);
|
||||
let contact = contact::find_by_i2p_address(&from).unwrap_or_default();
|
||||
let deciphered = neveko25519::cipher(&contact.nmpk, body, None).await;
|
||||
let _ = tx.send(deciphered);
|
||||
ctx.request_repaint();
|
||||
|
|
|
@ -140,9 +140,14 @@ impl Default for MarketApp {
|
|||
let (_refresh_on_delete_product_tx, _refresh_on_delete_product_rx) =
|
||||
std::sync::mpsc::channel();
|
||||
let read_product_image = std::fs::read("./assets/qr.png").unwrap_or(Vec::new());
|
||||
let s = db::DatabaseEnvironment::open(&utils::get_release_env().value()).unwrap();
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, contact::NEVEKO_VENDOR_ENABLED);
|
||||
let is_vendor_enabled = r == contact::NEVEKO_VENDOR_MODE_ON;
|
||||
let s = db::DatabaseEnvironment::open().unwrap();
|
||||
let r = db::DatabaseEnvironment::read(
|
||||
&s.env,
|
||||
&s.handle.unwrap(),
|
||||
&contact::NEVEKO_VENDOR_ENABLED.as_bytes().to_vec(),
|
||||
).unwrap();
|
||||
let sr: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
let is_vendor_enabled = sr == contact::NEVEKO_VENDOR_MODE_ON;
|
||||
let (contact_info_tx, contact_info_rx) = std::sync::mpsc::channel();
|
||||
let (get_vendor_products_tx, get_vendor_products_rx) = std::sync::mpsc::channel();
|
||||
let (get_vendor_product_tx, get_vendor_product_rx) = std::sync::mpsc::channel();
|
||||
|
@ -450,7 +455,8 @@ impl eframe::App for MarketApp {
|
|||
let prefix = String::from(crate::GUI_MSIG_ADJUDICATOR_DB_KEY);
|
||||
if !self.msig.query_adjudicator {
|
||||
let adjudicator_db =
|
||||
utils::search_gui_db(String::from(&prefix), self.m_order.orid.clone());
|
||||
utils::search_gui_db(String::from(&prefix), self.m_order.orid.clone())
|
||||
.unwrap_or_default();
|
||||
log::debug!("adjudicator db: {}", adjudicator_db);
|
||||
self.msig.has_adjudicator = !adjudicator_db.is_empty();
|
||||
self.msig.adjudicator = adjudicator_db;
|
||||
|
@ -464,7 +470,7 @@ impl eframe::App for MarketApp {
|
|||
prefix,
|
||||
self.m_order.orid.clone(),
|
||||
self.msig.adjudicator.clone(),
|
||||
);
|
||||
).unwrap();
|
||||
self.msig.has_adjudicator = true;
|
||||
}
|
||||
} else {
|
||||
|
@ -472,7 +478,7 @@ impl eframe::App for MarketApp {
|
|||
ui.label("\t");
|
||||
if !self.msig.completed_prepare {
|
||||
if ui.button("Clear Mediator").clicked() {
|
||||
utils::clear_gui_db(prefix, self.m_order.orid.clone());
|
||||
utils::clear_gui_db(prefix, self.m_order.orid.clone()).unwrap();
|
||||
self.msig.adjudicator = String::new();
|
||||
self.msig.has_adjudicator = false;
|
||||
self.msig.query_adjudicator = false;
|
||||
|
@ -490,9 +496,11 @@ impl eframe::App for MarketApp {
|
|||
String::from(crate::GUI_MSIG_ADJUDICATOR_DB_KEY);
|
||||
let vendor_prefix = String::from(crate::GUI_OVL_DB_KEY);
|
||||
let adjudicator =
|
||||
utils::search_gui_db(adjudicator_prefix, self.m_order.orid.clone());
|
||||
utils::search_gui_db(adjudicator_prefix, self.m_order.orid.clone())
|
||||
.unwrap_or_default();
|
||||
let vendor =
|
||||
utils::search_gui_db(vendor_prefix, self.m_order.orid.clone());
|
||||
utils::search_gui_db(vendor_prefix, self.m_order.orid.clone())
|
||||
.unwrap_or_default();
|
||||
// get prepare multisig info from vendor and adjudicator
|
||||
// call prepare multisig and save to db
|
||||
send_prepare_info_req(
|
||||
|
@ -508,9 +516,11 @@ impl eframe::App for MarketApp {
|
|||
String::from(crate::GUI_MSIG_ADJUDICATOR_DB_KEY);
|
||||
let vendor_prefix = String::from(crate::GUI_OVL_DB_KEY);
|
||||
let adjudicator =
|
||||
utils::search_gui_db(adjudicator_prefix, self.m_order.orid.clone());
|
||||
utils::search_gui_db(adjudicator_prefix, self.m_order.orid.clone())
|
||||
.unwrap_or_default();
|
||||
let vendor =
|
||||
utils::search_gui_db(vendor_prefix, self.m_order.orid.clone());
|
||||
utils::search_gui_db(vendor_prefix, self.m_order.orid.clone())
|
||||
.unwrap_or_default();
|
||||
let sub_type = String::from(message::PREPARE_MSIG);
|
||||
let is_prepared = validate_msig_step(
|
||||
&adjudicator,
|
||||
|
@ -531,9 +541,11 @@ impl eframe::App for MarketApp {
|
|||
String::from(crate::GUI_MSIG_ADJUDICATOR_DB_KEY);
|
||||
let vendor_prefix = String::from(crate::GUI_OVL_DB_KEY);
|
||||
let adjudicator =
|
||||
utils::search_gui_db(adjudicator_prefix, self.m_order.orid.clone());
|
||||
utils::search_gui_db(adjudicator_prefix, self.m_order.orid.clone())
|
||||
.unwrap_or_default();
|
||||
let vendor =
|
||||
utils::search_gui_db(vendor_prefix, self.m_order.orid.clone());
|
||||
utils::search_gui_db(vendor_prefix, self.m_order.orid.clone())
|
||||
.unwrap_or_default();
|
||||
// get make multisig info from vendor and adjudicator
|
||||
// call make multisig and save to db
|
||||
send_make_info_req(
|
||||
|
@ -549,9 +561,11 @@ impl eframe::App for MarketApp {
|
|||
String::from(crate::GUI_MSIG_ADJUDICATOR_DB_KEY);
|
||||
let vendor_prefix = String::from(crate::GUI_OVL_DB_KEY);
|
||||
let adjudicator =
|
||||
utils::search_gui_db(adjudicator_prefix, self.m_order.orid.clone());
|
||||
utils::search_gui_db(adjudicator_prefix, self.m_order.orid.clone())
|
||||
.unwrap_or_default();
|
||||
let vendor =
|
||||
utils::search_gui_db(vendor_prefix, self.m_order.orid.clone());
|
||||
utils::search_gui_db(vendor_prefix, self.m_order.orid.clone())
|
||||
.unwrap_or_default();
|
||||
let sub_type = String::from(message::MAKE_MSIG);
|
||||
let is_made = validate_msig_step(
|
||||
&adjudicator,
|
||||
|
@ -572,9 +586,11 @@ impl eframe::App for MarketApp {
|
|||
String::from(crate::GUI_MSIG_ADJUDICATOR_DB_KEY);
|
||||
let vendor_prefix = String::from(crate::GUI_OVL_DB_KEY);
|
||||
let adjudicator =
|
||||
utils::search_gui_db(adjudicator_prefix, self.m_order.orid.clone());
|
||||
utils::search_gui_db(adjudicator_prefix, self.m_order.orid.clone())
|
||||
.unwrap_or_default();
|
||||
let vendor =
|
||||
utils::search_gui_db(vendor_prefix, self.m_order.orid.clone());
|
||||
utils::search_gui_db(vendor_prefix, self.m_order.orid.clone())
|
||||
.unwrap_or_default();
|
||||
// get kex round one info from vendor and adjudicator
|
||||
// call make multisig and save to db
|
||||
send_kex_initial_req(
|
||||
|
@ -590,9 +606,11 @@ impl eframe::App for MarketApp {
|
|||
String::from(crate::GUI_MSIG_ADJUDICATOR_DB_KEY);
|
||||
let vendor_prefix = String::from(crate::GUI_OVL_DB_KEY);
|
||||
let adjudicator =
|
||||
utils::search_gui_db(adjudicator_prefix, self.m_order.orid.clone());
|
||||
utils::search_gui_db(adjudicator_prefix, self.m_order.orid.clone())
|
||||
.unwrap_or_default();
|
||||
let vendor =
|
||||
utils::search_gui_db(vendor_prefix, self.m_order.orid.clone());
|
||||
utils::search_gui_db(vendor_prefix, self.m_order.orid.clone())
|
||||
.unwrap_or_default();
|
||||
let sub_type = String::from(message::KEX_ONE_MSIG);
|
||||
let is_made = validate_msig_step(
|
||||
&adjudicator,
|
||||
|
@ -613,9 +631,11 @@ impl eframe::App for MarketApp {
|
|||
String::from(crate::GUI_MSIG_ADJUDICATOR_DB_KEY);
|
||||
let vendor_prefix = String::from(crate::GUI_OVL_DB_KEY);
|
||||
let adjudicator =
|
||||
utils::search_gui_db(adjudicator_prefix, self.m_order.orid.clone());
|
||||
utils::search_gui_db(adjudicator_prefix, self.m_order.orid.clone())
|
||||
.unwrap_or_default();
|
||||
let vendor =
|
||||
utils::search_gui_db(vendor_prefix, self.m_order.orid.clone());
|
||||
utils::search_gui_db(vendor_prefix, self.m_order.orid.clone())
|
||||
.unwrap_or_default();
|
||||
// get kex round two info from vendor and adjudicator
|
||||
// call make multisig and save to db
|
||||
send_kex_final_req(
|
||||
|
@ -631,9 +651,11 @@ impl eframe::App for MarketApp {
|
|||
String::from(crate::GUI_MSIG_ADJUDICATOR_DB_KEY);
|
||||
let vendor_prefix = String::from(crate::GUI_OVL_DB_KEY);
|
||||
let adjudicator =
|
||||
utils::search_gui_db(adjudicator_prefix, self.m_order.orid.clone());
|
||||
utils::search_gui_db(adjudicator_prefix, self.m_order.orid.clone())
|
||||
.unwrap_or_default();
|
||||
let vendor =
|
||||
utils::search_gui_db(vendor_prefix, self.m_order.orid.clone());
|
||||
utils::search_gui_db(vendor_prefix, self.m_order.orid.clone())
|
||||
.unwrap_or_default();
|
||||
let sub_type = String::from(message::KEX_TWO_MSIG);
|
||||
let is_made = validate_msig_step(
|
||||
&adjudicator,
|
||||
|
@ -662,7 +684,8 @@ impl eframe::App for MarketApp {
|
|||
self.is_loading = true;
|
||||
let vendor_prefix = String::from(crate::GUI_OVL_DB_KEY);
|
||||
let contact =
|
||||
utils::search_gui_db(vendor_prefix, self.m_order.orid.clone());
|
||||
utils::search_gui_db(vendor_prefix, self.m_order.orid.clone())
|
||||
.unwrap_or_default();
|
||||
verify_order_wallet_funded(
|
||||
&contact,
|
||||
&self.m_order.orid,
|
||||
|
@ -679,7 +702,8 @@ impl eframe::App for MarketApp {
|
|||
self.is_loading = true;
|
||||
let vendor_prefix = String::from(crate::GUI_OVL_DB_KEY);
|
||||
let vendor =
|
||||
utils::search_gui_db(vendor_prefix, self.m_order.orid.clone());
|
||||
utils::search_gui_db(vendor_prefix, self.m_order.orid.clone())
|
||||
.unwrap_or_default();
|
||||
// not much orchestration here afaik, just send the output to the vendor
|
||||
// TODO(c2m): 'idk remember why this tx.clone() is being reused' but not
|
||||
// nothing breaks for now...
|
||||
|
@ -694,7 +718,7 @@ impl eframe::App for MarketApp {
|
|||
let info = utils::search_gui_db(
|
||||
String::from(crate::GUI_MSIG_EXPORT_DB_KEY),
|
||||
String::from(&self.m_order.orid.clone()),
|
||||
);
|
||||
).unwrap_or_default();
|
||||
if !info.is_empty() {
|
||||
self.msig.completed_export = true;
|
||||
}
|
||||
|
@ -711,7 +735,8 @@ impl eframe::App for MarketApp {
|
|||
)
|
||||
.on_hover_text("Please wait for the vendor to upload delivery info.");
|
||||
if ui.button("Check").clicked() {
|
||||
let order = order::find(&self.m_order.orid.clone());
|
||||
let order = order::find(&self.m_order.orid.clone())
|
||||
.unwrap_or_default();
|
||||
if order.status == order::StatusType::Shipped.value() {
|
||||
self.msig.completed_shipping_request = true;
|
||||
}
|
||||
|
@ -753,7 +778,8 @@ impl eframe::App for MarketApp {
|
|||
self.is_loading = true;
|
||||
let vendor_prefix = String::from(crate::GUI_OVL_DB_KEY);
|
||||
let vendor =
|
||||
utils::search_gui_db(vendor_prefix, self.m_order.orid.clone());
|
||||
utils::search_gui_db(vendor_prefix, self.m_order.orid.clone())
|
||||
.unwrap_or_default();
|
||||
// async trigger for signing and submitted the txset
|
||||
release_txset(
|
||||
vendor,
|
||||
|
@ -898,7 +924,7 @@ impl eframe::App for MarketApp {
|
|||
let e_info: String = utils::search_gui_db(
|
||||
String::from(neveko_core::DELIVERY_INFO_DB_KEY),
|
||||
String::from(&o.orid),
|
||||
);
|
||||
).unwrap_or_default();
|
||||
cipher_req(
|
||||
String::from(&o.cid),
|
||||
e_info,
|
||||
|
@ -917,7 +943,7 @@ impl eframe::App for MarketApp {
|
|||
let vendor = utils::search_gui_db(
|
||||
vendor_prefix,
|
||||
self.m_order.orid.clone(),
|
||||
);
|
||||
).unwrap_or_default();
|
||||
self.is_loading = true;
|
||||
cancel_order_req(
|
||||
self.cancel_request_tx.clone(),
|
||||
|
@ -936,7 +962,7 @@ impl eframe::App for MarketApp {
|
|||
let vendor = utils::search_gui_db(
|
||||
vendor_prefix,
|
||||
self.m_order.orid.clone(),
|
||||
);
|
||||
).unwrap_or_default();
|
||||
self.is_loading = true;
|
||||
create_dispute_req(
|
||||
&self.m_order.orid.clone(),
|
||||
|
@ -971,7 +997,8 @@ impl eframe::App for MarketApp {
|
|||
}
|
||||
let adjudicator_prefix = String::from(crate::GUI_MSIG_ADJUDICATOR_DB_KEY);
|
||||
let adjudicator =
|
||||
utils::search_gui_db(adjudicator_prefix, self.m_order.orid.clone());
|
||||
utils::search_gui_db(adjudicator_prefix, self.m_order.orid.clone())
|
||||
.unwrap_or_default();
|
||||
ui.label(format!("customer id: {}", self.new_order.cid));
|
||||
ui.label(format!("adjudicator id: {}", adjudicator));
|
||||
ui.label(format!("product id: {}", self.new_order.pid));
|
||||
|
@ -1145,7 +1172,7 @@ impl eframe::App for MarketApp {
|
|||
let nick_db = utils::search_gui_db(
|
||||
String::from(crate::GUI_NICK_DB_KEY),
|
||||
String::from(&v.i2p_address),
|
||||
);
|
||||
).unwrap_or_default();
|
||||
let nick = if nick_db.is_empty() {
|
||||
String::from("anon")
|
||||
} else {
|
||||
|
@ -1157,16 +1184,16 @@ impl eframe::App for MarketApp {
|
|||
self.vendor_status.txp = utils::search_gui_db(
|
||||
String::from(crate::GUI_TX_PROOF_DB_KEY),
|
||||
String::from(&v.i2p_address),
|
||||
);
|
||||
).unwrap_or_default();
|
||||
// get the jwp
|
||||
self.vendor_status.jwp = utils::search_gui_db(
|
||||
String::from(crate::GUI_JWP_DB_KEY),
|
||||
String::from(&v.i2p_address),
|
||||
);
|
||||
).unwrap_or_default();
|
||||
let r_exp = utils::search_gui_db(
|
||||
String::from(crate::GUI_EXP_DB_KEY),
|
||||
String::from(&v.i2p_address),
|
||||
);
|
||||
).unwrap_or_default();
|
||||
self.vendor_status.exp = r_exp;
|
||||
let expire = match self.vendor_status.exp.parse::<i64>()
|
||||
{
|
||||
|
@ -1366,7 +1393,8 @@ impl eframe::App for MarketApp {
|
|||
String::from(&p.pid),
|
||||
);
|
||||
} else {
|
||||
let i_product = product::find(&p.pid);
|
||||
let i_product = product::find(&p.pid)
|
||||
.unwrap_or_default();
|
||||
match std::fs::write(&file_path, &i_product.image) {
|
||||
Ok(w) => w,
|
||||
Err(_) => {
|
||||
|
@ -1494,14 +1522,14 @@ impl eframe::App for MarketApp {
|
|||
qty,
|
||||
};
|
||||
let j_product = utils::product_to_json(&product);
|
||||
product::modify(j_product);
|
||||
product::modify(j_product).unwrap();
|
||||
self.new_product_desc = String::new();
|
||||
self.new_product_name = String::new();
|
||||
self.new_product_price = String::new();
|
||||
self.new_product_qty = String::new();
|
||||
self.new_product_image = String::new();
|
||||
self.is_showing_product_update = false;
|
||||
self.products = product::find_all();
|
||||
self.products = product::find_all().unwrap_or_default();
|
||||
}
|
||||
if ui.button("Exit").clicked() {
|
||||
self.new_product_desc = String::new();
|
||||
|
@ -1619,8 +1647,8 @@ impl eframe::App for MarketApp {
|
|||
.on_hover_text("monero multisig is experimental and usage of neveko may lead to loss of funds.");
|
||||
});
|
||||
if ui.button("Refresh").clicked() {
|
||||
self.products = product::find_all();
|
||||
self.orders = order::find_all();
|
||||
self.products = product::find_all().unwrap_or_default();
|
||||
self.orders = order::find_all().unwrap_or_default();
|
||||
}
|
||||
ui.horizontal(|ui| {
|
||||
let vendor_mode: &str = if self.is_vendor_enabled {
|
||||
|
@ -1630,17 +1658,17 @@ impl eframe::App for MarketApp {
|
|||
};
|
||||
ui.label(format!("vendor mode: {} \t", vendor_mode));
|
||||
if ui.button("toggle").clicked() {
|
||||
self.is_vendor_enabled = utils::toggle_vendor_enabled();
|
||||
self.is_vendor_enabled = utils::toggle_vendor_enabled().unwrap_or_default();
|
||||
}
|
||||
});
|
||||
if ui.button("View Vendors").clicked() {
|
||||
// assume all contacts are vendors until updated status check
|
||||
self.vendors = contact::find_all();
|
||||
self.vendors = contact::find_all().unwrap_or_default();
|
||||
self.is_showing_vendors = true;
|
||||
}
|
||||
ui.label("\n");
|
||||
if ui.button("View Orders").clicked() {
|
||||
self.customer_orders = order::find_all_backup();
|
||||
self.customer_orders = order::find_all_backup().unwrap_or_default();
|
||||
self.is_customer_viewing_orders = true;
|
||||
}
|
||||
if self.is_vendor_enabled {
|
||||
|
@ -1697,7 +1725,7 @@ impl eframe::App for MarketApp {
|
|||
qty,
|
||||
};
|
||||
let j_product = utils::product_to_json(&product);
|
||||
product::create(j_product);
|
||||
product::create(j_product).unwrap();
|
||||
self.new_product_desc = String::new();
|
||||
self.new_product_name = String::new();
|
||||
self.new_product_price = String::new();
|
||||
|
@ -1706,14 +1734,14 @@ impl eframe::App for MarketApp {
|
|||
}
|
||||
ui.label("\n");
|
||||
if ui.button("View Products").clicked() {
|
||||
self.products = product::find_all();
|
||||
self.products = product::find_all().unwrap_or_default();
|
||||
self.is_showing_products = true;
|
||||
self.is_showing_vendors = false;
|
||||
}
|
||||
ui.label("\n");
|
||||
if ui.button("Manage Orders").clicked() {
|
||||
self.is_showing_orders = true;
|
||||
self.orders = order::find_all_vendor_orders();
|
||||
self.orders = order::find_all_vendor_orders().unwrap_or_default();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -1806,11 +1834,11 @@ fn submit_order_req(
|
|||
let order = order::transmit_order_request(r_contact, jwp, request).await;
|
||||
let u_order = order.unwrap_or_else(|_| Default::default());
|
||||
// cache order request to db
|
||||
order::backup(&u_order);
|
||||
order::backup(&u_order).unwrap();
|
||||
let prefix = String::from(crate::GUI_OVL_DB_KEY);
|
||||
let orid = String::from(&u_order.orid);
|
||||
let i2p = String::from(&contact);
|
||||
utils::write_gui_db(prefix, orid, i2p);
|
||||
utils::write_gui_db(prefix, orid, i2p).unwrap();
|
||||
let _ = tx.send(u_order);
|
||||
ctx.request_repaint();
|
||||
});
|
||||
|
@ -1830,9 +1858,10 @@ fn send_prepare_info_req(
|
|||
let m_jwp: String = utils::search_gui_db(
|
||||
String::from(crate::GUI_JWP_DB_KEY),
|
||||
String::from(&adjudicator),
|
||||
);
|
||||
).unwrap_or_default();
|
||||
let v_jwp: String =
|
||||
utils::search_gui_db(String::from(crate::GUI_JWP_DB_KEY), String::from(&vendor));
|
||||
utils::search_gui_db(String::from(crate::GUI_JWP_DB_KEY), String::from(&vendor))
|
||||
.unwrap_or_default();
|
||||
let wallet_password = String::new();
|
||||
monero::create_wallet(&w_orid, &wallet_password).await;
|
||||
let m_wallet = monero::open_wallet(&w_orid, &wallet_password).await;
|
||||
|
@ -1850,10 +1879,10 @@ fn send_prepare_info_req(
|
|||
String::from(crate::GUI_MSIG_PREPARE_DB_KEY),
|
||||
String::from(&w_orid),
|
||||
String::from(ref_prepare_info),
|
||||
);
|
||||
).unwrap();
|
||||
// Request adjudicator and vendor while we're at it
|
||||
// Will coordinating send this on make requests next
|
||||
let s = db::DatabaseEnvironment::async_open().await;
|
||||
let s = db::DatabaseEnvironment::open().unwrap();
|
||||
let m_msig_key = format!(
|
||||
"{}-{}-{}",
|
||||
message::PREPARE_MSIG,
|
||||
|
@ -1866,8 +1895,9 @@ fn send_prepare_info_req(
|
|||
String::from(&v_orid),
|
||||
vendor
|
||||
);
|
||||
let m_prepare = db::DatabaseEnvironment::async_read(&s.env, &s.handle, &m_msig_key).await;
|
||||
let v_prepare = db::DatabaseEnvironment::async_read(&s.env, &s.handle, &v_msig_key).await;
|
||||
let m_prepare = db::DatabaseEnvironment::read(&s.env, &s.handle.unwrap(), &m_msig_key.as_bytes().to_vec()).unwrap();
|
||||
let s = db::DatabaseEnvironment::open().unwrap();
|
||||
let v_prepare = db::DatabaseEnvironment::read(&s.env, &s.handle.unwrap(), &v_msig_key.as_bytes().to_vec()).unwrap();
|
||||
if v_prepare.is_empty() {
|
||||
log::debug!(
|
||||
"constructing vendor {} msig messages",
|
||||
|
@ -1918,9 +1948,10 @@ fn send_make_info_req(
|
|||
let m_jwp: String = utils::search_gui_db(
|
||||
String::from(crate::GUI_JWP_DB_KEY),
|
||||
String::from(&adjudicator),
|
||||
);
|
||||
).unwrap_or_default();
|
||||
let v_jwp: String =
|
||||
utils::search_gui_db(String::from(crate::GUI_JWP_DB_KEY), String::from(&vendor));
|
||||
utils::search_gui_db(String::from(crate::GUI_JWP_DB_KEY), String::from(&vendor))
|
||||
.unwrap_or_default();
|
||||
let wallet_password = String::new();
|
||||
let m_wallet = monero::open_wallet(&w_orid, &wallet_password).await;
|
||||
if !m_wallet {
|
||||
|
@ -1938,7 +1969,7 @@ fn send_make_info_req(
|
|||
String::from(crate::GUI_MSIG_PREPARE_DB_KEY),
|
||||
String::from(&w_orid),
|
||||
);
|
||||
let s = db::DatabaseEnvironment::async_open().await;
|
||||
let s = db::DatabaseEnvironment::open().unwrap();
|
||||
let m_msig_key = format!(
|
||||
"{}-{}-{}",
|
||||
message::PREPARE_MSIG,
|
||||
|
@ -1951,18 +1982,22 @@ fn send_make_info_req(
|
|||
String::from(&v_orid),
|
||||
vendor
|
||||
);
|
||||
let m_prepare = db::DatabaseEnvironment::async_read(&s.env, &s.handle, &m_msig_key).await;
|
||||
let v_prepare = db::DatabaseEnvironment::async_read(&s.env, &s.handle, &v_msig_key).await;
|
||||
prepare_info_prep.push(String::from(&m_prepare));
|
||||
prepare_info_prep.push(String::from(&v_prepare));
|
||||
m_prepare_info_send.push(String::from(&c_prepare));
|
||||
m_prepare_info_send.push(String::from(&v_prepare));
|
||||
v_prepare_info_send.push(String::from(&m_prepare));
|
||||
v_prepare_info_send.push(String::from(&c_prepare));
|
||||
let m_prepare = db::DatabaseEnvironment::read(&s.env, &s.handle.unwrap(), &m_msig_key.as_bytes().to_vec()).unwrap();
|
||||
let sm_prepare: String = bincode::deserialize(&m_prepare[..]).unwrap_or_default();
|
||||
let s = db::DatabaseEnvironment::open().unwrap();
|
||||
let v_prepare = db::DatabaseEnvironment::read(&s.env, &s.handle.unwrap(), &v_msig_key.as_bytes().to_vec()).unwrap();
|
||||
let sv_prepare: String = bincode::deserialize(&&v_prepare[..]).unwrap_or_default();
|
||||
prepare_info_prep.push(String::from(&sm_prepare));
|
||||
prepare_info_prep.push(String::from(&sv_prepare));
|
||||
let uc_prepare = c_prepare.unwrap_or_default();
|
||||
m_prepare_info_send.push(String::from(&uc_prepare));
|
||||
m_prepare_info_send.push(String::from(&sv_prepare));
|
||||
v_prepare_info_send.push(String::from(&sv_prepare));
|
||||
v_prepare_info_send.push(String::from(&uc_prepare));
|
||||
let local_make = utils::search_gui_db(
|
||||
String::from(crate::GUI_MSIG_MAKE_DB_KEY),
|
||||
String::from(&w_orid),
|
||||
);
|
||||
).unwrap_or_default();
|
||||
if local_make.is_empty() {
|
||||
let make_info = monero::make_wallet(prepare_info_prep).await;
|
||||
monero::close_wallet(&w_orid, &wallet_password).await;
|
||||
|
@ -1972,13 +2007,12 @@ fn send_make_info_req(
|
|||
String::from(crate::GUI_MSIG_MAKE_DB_KEY),
|
||||
String::from(&w_orid),
|
||||
String::from(ref_make_info),
|
||||
);
|
||||
).unwrap();
|
||||
}
|
||||
}
|
||||
// Request adjudicator and vendor while we're at it
|
||||
// Will coordinating send this on make requests next
|
||||
|
||||
let s = db::DatabaseEnvironment::async_open().await;
|
||||
let s = db::DatabaseEnvironment::open().unwrap();
|
||||
let m_msig_key = format!(
|
||||
"{}-{}-{}",
|
||||
message::MAKE_MSIG,
|
||||
|
@ -1991,8 +2025,9 @@ fn send_make_info_req(
|
|||
String::from(&v_orid),
|
||||
vendor
|
||||
);
|
||||
let m_make = db::DatabaseEnvironment::async_read(&s.env, &s.handle, &m_msig_key).await;
|
||||
let v_make = db::DatabaseEnvironment::async_read(&s.env, &s.handle, &v_msig_key).await;
|
||||
let m_make = db::DatabaseEnvironment::read(&s.env, &s.handle.unwrap(), &m_msig_key.as_bytes().to_vec()).unwrap();
|
||||
let s = db::DatabaseEnvironment::open().unwrap();
|
||||
let v_make = db::DatabaseEnvironment::read(&s.env, &s.handle.unwrap(), &v_msig_key.as_bytes().to_vec()).unwrap();
|
||||
if v_make.is_empty() {
|
||||
log::debug!("constructing vendor {} msig messages", message::MAKE_MSIG);
|
||||
let v_msig_request: reqres::MultisigInfoRequest = reqres::MultisigInfoRequest {
|
||||
|
@ -2040,9 +2075,10 @@ fn send_kex_initial_req(
|
|||
let m_jwp: String = utils::search_gui_db(
|
||||
String::from(crate::GUI_JWP_DB_KEY),
|
||||
String::from(&adjudicator),
|
||||
);
|
||||
).unwrap_or_default();
|
||||
let v_jwp: String =
|
||||
utils::search_gui_db(String::from(crate::GUI_JWP_DB_KEY), String::from(&vendor));
|
||||
utils::search_gui_db(String::from(crate::GUI_JWP_DB_KEY), String::from(&vendor))
|
||||
.unwrap_or_default();
|
||||
let wallet_password = String::new();
|
||||
let m_wallet = monero::open_wallet(&w_orid, &wallet_password).await;
|
||||
if !m_wallet {
|
||||
|
@ -2059,8 +2095,8 @@ fn send_kex_initial_req(
|
|||
let c_kex_init = utils::search_gui_db(
|
||||
String::from(crate::GUI_MSIG_MAKE_DB_KEY),
|
||||
String::from(&w_orid),
|
||||
);
|
||||
let s = db::DatabaseEnvironment::async_open().await;
|
||||
).unwrap_or_default();
|
||||
let s = db::DatabaseEnvironment::open().unwrap();
|
||||
let m_msig_key = format!(
|
||||
"{}-{}-{}",
|
||||
message::MAKE_MSIG,
|
||||
|
@ -2073,18 +2109,21 @@ fn send_kex_initial_req(
|
|||
String::from(&v_orid),
|
||||
vendor
|
||||
);
|
||||
let m_kex_init = db::DatabaseEnvironment::async_read(&s.env, &s.handle, &m_msig_key).await;
|
||||
let v_kex_init = db::DatabaseEnvironment::async_read(&s.env, &s.handle, &v_msig_key).await;
|
||||
kex_init_prep.push(String::from(&m_kex_init));
|
||||
kex_init_prep.push(String::from(&v_kex_init));
|
||||
let m_kex_init = db::DatabaseEnvironment::read(&s.env, &s.handle.unwrap(), &m_msig_key.as_bytes().to_vec()).unwrap();
|
||||
let sm_kex_init: String = bincode::deserialize(&m_kex_init[..]).unwrap_or_default();
|
||||
let s = db::DatabaseEnvironment::open().unwrap();
|
||||
let v_kex_init = db::DatabaseEnvironment::read(&s.env, &s.handle.unwrap(), &v_msig_key.as_bytes().to_vec()).unwrap();
|
||||
let sv_kex_init: String = bincode::deserialize(&v_kex_init[..]).unwrap_or_default();
|
||||
kex_init_prep.push(String::from(&sm_kex_init));
|
||||
kex_init_prep.push(String::from(&sv_kex_init));
|
||||
m_kex_init_send.push(String::from(&c_kex_init));
|
||||
m_kex_init_send.push(String::from(&v_kex_init));
|
||||
v_kex_init_send.push(String::from(&m_kex_init));
|
||||
m_kex_init_send.push(String::from(&sv_kex_init));
|
||||
v_kex_init_send.push(String::from(&sm_kex_init));
|
||||
v_kex_init_send.push(String::from(&c_kex_init));
|
||||
let local_kex_init = utils::search_gui_db(
|
||||
String::from(crate::GUI_MSIG_KEX_ONE_DB_KEY),
|
||||
String::from(&w_orid),
|
||||
);
|
||||
).unwrap_or_default();
|
||||
if local_kex_init.is_empty() {
|
||||
let kex_out =
|
||||
monero::exchange_multisig_keys(false, kex_init_prep, &wallet_password).await;
|
||||
|
@ -2095,12 +2134,12 @@ fn send_kex_initial_req(
|
|||
String::from(crate::GUI_MSIG_KEX_ONE_DB_KEY),
|
||||
String::from(&w_orid),
|
||||
String::from(ref_kex_info),
|
||||
);
|
||||
).unwrap();
|
||||
}
|
||||
}
|
||||
// Request adjudicator and vendor while we're at it
|
||||
// Will coordinating send this on kex round two next
|
||||
let s = db::DatabaseEnvironment::async_open().await;
|
||||
let s = db::DatabaseEnvironment::open().unwrap();
|
||||
let m_msig_key = format!(
|
||||
"{}-{}-{}",
|
||||
message::KEX_ONE_MSIG,
|
||||
|
@ -2113,8 +2152,9 @@ fn send_kex_initial_req(
|
|||
String::from(&v_orid),
|
||||
vendor
|
||||
);
|
||||
let m_kex_init = db::DatabaseEnvironment::async_read(&s.env, &s.handle, &m_msig_key).await;
|
||||
let v_kex_init = db::DatabaseEnvironment::async_read(&s.env, &s.handle, &v_msig_key).await;
|
||||
let m_kex_init = db::DatabaseEnvironment::read(&s.env, &s.handle.unwrap(), &m_msig_key.as_bytes().to_vec()).unwrap();
|
||||
let s = db::DatabaseEnvironment::open().unwrap();
|
||||
let v_kex_init = db::DatabaseEnvironment::read(&s.env, &s.handle.unwrap(), &v_msig_key.as_bytes().to_vec()).unwrap();
|
||||
if v_kex_init.is_empty() {
|
||||
log::debug!(
|
||||
"constructing vendor {} msig messages",
|
||||
|
@ -2165,9 +2205,10 @@ fn send_kex_final_req(
|
|||
let m_jwp: String = utils::search_gui_db(
|
||||
String::from(crate::GUI_JWP_DB_KEY),
|
||||
String::from(&adjudicator),
|
||||
);
|
||||
).unwrap_or_default();
|
||||
let v_jwp: String =
|
||||
utils::search_gui_db(String::from(crate::GUI_JWP_DB_KEY), String::from(&vendor));
|
||||
utils::search_gui_db(String::from(crate::GUI_JWP_DB_KEY), String::from(&vendor))
|
||||
.unwrap_or_default();
|
||||
let wallet_password = String::new();
|
||||
let m_wallet = monero::open_wallet(&w_orid, &wallet_password).await;
|
||||
if !m_wallet {
|
||||
|
@ -2182,8 +2223,8 @@ fn send_kex_final_req(
|
|||
let c_kex_final = utils::search_gui_db(
|
||||
String::from(crate::GUI_MSIG_KEX_ONE_DB_KEY),
|
||||
String::from(&w_orid),
|
||||
);
|
||||
let s = db::DatabaseEnvironment::async_open().await;
|
||||
).unwrap_or_default();
|
||||
let s = db::DatabaseEnvironment::open().unwrap();
|
||||
let m_msig_key = format!(
|
||||
"{}-{}-{}",
|
||||
message::KEX_ONE_MSIG,
|
||||
|
@ -2196,8 +2237,11 @@ fn send_kex_final_req(
|
|||
String::from(&v_orid),
|
||||
vendor
|
||||
);
|
||||
let m_kex_final = db::DatabaseEnvironment::async_read(&s.env, &s.handle, &m_msig_key).await;
|
||||
let v_kex_final = db::DatabaseEnvironment::async_read(&s.env, &s.handle, &v_msig_key).await;
|
||||
let r_m_kex_final = db::DatabaseEnvironment::read(&s.env, &s.handle.unwrap(), &m_msig_key.as_bytes().to_vec()).unwrap();
|
||||
let s = db::DatabaseEnvironment::open().unwrap();
|
||||
let r_v_kex_final = db::DatabaseEnvironment::read(&s.env, &s.handle.unwrap(), &v_msig_key.as_bytes().to_vec()).unwrap();
|
||||
let m_kex_final: String = bincode::deserialize(&r_m_kex_final[..]).unwrap_or_default();
|
||||
let v_kex_final: String = bincode::deserialize(&r_v_kex_final[..]).unwrap_or_default();
|
||||
kex_final_prep.push(String::from(&m_kex_final));
|
||||
kex_final_prep.push(String::from(&v_kex_final));
|
||||
m_kex_final_send.push(String::from(&c_kex_final));
|
||||
|
@ -2207,7 +2251,7 @@ fn send_kex_final_req(
|
|||
let local_kex_final = utils::search_gui_db(
|
||||
String::from(crate::GUI_MSIG_KEX_TWO_DB_KEY),
|
||||
String::from(&w_orid),
|
||||
);
|
||||
).unwrap_or_default();
|
||||
if local_kex_final.is_empty() {
|
||||
let kex_out =
|
||||
monero::exchange_multisig_keys(false, kex_final_prep, &wallet_password).await;
|
||||
|
@ -2218,11 +2262,11 @@ fn send_kex_final_req(
|
|||
String::from(crate::GUI_MSIG_KEX_TWO_DB_KEY),
|
||||
String::from(&w_orid),
|
||||
String::from(ref_kex_info),
|
||||
);
|
||||
).unwrap_or_default();
|
||||
}
|
||||
}
|
||||
// we can verify all good if the senders all send back the correct wallet address
|
||||
let s = db::DatabaseEnvironment::async_open().await;
|
||||
let s = db::DatabaseEnvironment::open().unwrap();
|
||||
let m_msig_key = format!(
|
||||
"{}-{}-{}",
|
||||
message::KEX_TWO_MSIG,
|
||||
|
@ -2235,8 +2279,9 @@ fn send_kex_final_req(
|
|||
String::from(&v_orid),
|
||||
vendor
|
||||
);
|
||||
let m_kex_final = db::DatabaseEnvironment::async_read(&s.env, &s.handle, &m_msig_key).await;
|
||||
let v_kex_final = db::DatabaseEnvironment::async_read(&s.env, &s.handle, &v_msig_key).await;
|
||||
let m_kex_final = db::DatabaseEnvironment::read(&s.env, &s.handle.unwrap(), &m_msig_key.as_bytes().to_vec()).unwrap();
|
||||
let s = db::DatabaseEnvironment::open().unwrap();
|
||||
let v_kex_final = db::DatabaseEnvironment::read(&s.env, &s.handle.unwrap(), &v_msig_key.as_bytes().to_vec()).unwrap();
|
||||
if v_kex_final.is_empty() {
|
||||
log::debug!(
|
||||
"constructing vendor {} msig messages",
|
||||
|
@ -2305,10 +2350,11 @@ fn verify_order_wallet_funded(
|
|||
return;
|
||||
}
|
||||
monero::close_wallet(&order_id, &wallet_password).await;
|
||||
let order = order::find(&order_id);
|
||||
let order = order::find(&order_id).unwrap_or_default();
|
||||
let vendor = String::from(&l_contact);
|
||||
let v_jwp: String =
|
||||
utils::search_gui_db(String::from(crate::GUI_JWP_DB_KEY), String::from(&vendor));
|
||||
utils::search_gui_db(String::from(crate::GUI_JWP_DB_KEY), String::from(&vendor))
|
||||
.unwrap_or_default();
|
||||
let opid = String::from(&order.pid);
|
||||
let result = product::get_vendor_product(vendor, v_jwp, opid).await;
|
||||
if !result.is_ok() {
|
||||
|
@ -2333,7 +2379,8 @@ fn send_import_info_req(tx: Sender<String>, ctx: egui::Context, orid: &String, v
|
|||
let w_orid: String = String::from(orid);
|
||||
tokio::spawn(async move {
|
||||
let v_jwp: String =
|
||||
utils::search_gui_db(String::from(crate::GUI_JWP_DB_KEY), String::from(&vendor));
|
||||
utils::search_gui_db(String::from(crate::GUI_JWP_DB_KEY), String::from(&vendor))
|
||||
.unwrap_or_default();
|
||||
let wallet_password = String::new();
|
||||
let m_wallet = monero::open_wallet(&w_orid, &wallet_password).await;
|
||||
if !m_wallet {
|
||||
|
@ -2350,17 +2397,17 @@ fn send_import_info_req(tx: Sender<String>, ctx: egui::Context, orid: &String, v
|
|||
String::from(crate::GUI_MSIG_EXPORT_DB_KEY),
|
||||
String::from(&w_orid),
|
||||
String::from(ref_export_info),
|
||||
);
|
||||
).unwrap_or_default();
|
||||
// Request vendor while we're at it
|
||||
// Will coordinating send this on make requests next
|
||||
let s = db::DatabaseEnvironment::async_open().await;
|
||||
let s = db::DatabaseEnvironment::open().unwrap();
|
||||
let v_msig_key = format!(
|
||||
"{}-{}-{}",
|
||||
message::EXPORT_MSIG,
|
||||
String::from(&v_orid),
|
||||
vendor
|
||||
);
|
||||
let v_export = db::DatabaseEnvironment::async_read(&s.env, &s.handle, &v_msig_key).await;
|
||||
let v_export = db::DatabaseEnvironment::read(&s.env, &s.handle.unwrap(), &v_msig_key.as_bytes().to_vec()).unwrap();
|
||||
if v_export.is_empty() {
|
||||
log::debug!("constructing vendor {} msig messages", message::EXPORT_MSIG);
|
||||
let v_msig_request: reqres::MultisigInfoRequest = reqres::MultisigInfoRequest {
|
||||
|
@ -2410,7 +2457,7 @@ fn cancel_order_req(
|
|||
tokio::spawn(async move {
|
||||
log::info!("cancel order req: {}", ship_orid);
|
||||
let order = order::d_trigger_cancel_request(&vendor_i2p, &ship_orid).await;
|
||||
let _ = tx.send(order);
|
||||
let _ = tx.send(order.unwrap_or_default());
|
||||
ctx.request_repaint();
|
||||
});
|
||||
}
|
||||
|
@ -2422,11 +2469,14 @@ fn validate_msig_step(
|
|||
vendor: &String,
|
||||
sub_type: &String,
|
||||
) -> bool {
|
||||
let s = db::DatabaseEnvironment::open(&utils::get_release_env().value()).unwrap();
|
||||
let s = db::DatabaseEnvironment::open().unwrap();
|
||||
let m_msig_key = format!("{}-{}-{}", sub_type, orid, adjudicator);
|
||||
let v_msig_key = format!("{}-{}-{}", sub_type, orid, vendor);
|
||||
let m_info = db::DatabaseEnvironment::read(&s.env, &s.handle, &m_msig_key);
|
||||
let v_info = db::DatabaseEnvironment::read(&s.env, &s.handle, &v_msig_key);
|
||||
let r_m_info = db::DatabaseEnvironment::read(&s.env, &s.handle.unwrap(), &m_msig_key.as_bytes().to_vec()).unwrap();
|
||||
let s = db::DatabaseEnvironment::open().unwrap();
|
||||
let r_v_info = db::DatabaseEnvironment::read(&s.env, &s.handle.unwrap(), &v_msig_key.as_bytes().to_vec()).unwrap();
|
||||
let m_info: String = bincode::deserialize(&&r_m_info[..]).unwrap_or_default();
|
||||
let v_info: String = bincode::deserialize(&&r_v_info[..]).unwrap_or_default();
|
||||
log::debug!("{} adjudicator info: {}", sub_type, &m_info);
|
||||
log::debug!("{} vendor info: {}", sub_type, &v_info);
|
||||
!m_info.is_empty() && !v_info.is_empty()
|
||||
|
@ -2435,14 +2485,15 @@ fn validate_msig_step(
|
|||
fn release_txset(contact: String, orid: String, ctx: egui::Context, tx: Sender<bool>) {
|
||||
tokio::spawn(async move {
|
||||
log::info!("async release txset");
|
||||
let lookup = order::find(&orid);
|
||||
let lookup = order::find(&orid).unwrap_or_default();
|
||||
let submit = order::sign_and_submit_multisig(&orid, &lookup.vend_msig_txset).await;
|
||||
if submit.result.tx_hash_list.is_empty() {
|
||||
log::error!("could not submit txset");
|
||||
let _ = tx.send(false);
|
||||
return;
|
||||
}
|
||||
let finalize = order::d_trigger_finalize_request(&contact, &orid).await;
|
||||
let t_finalize = order::d_trigger_finalize_request(&contact, &orid).await;
|
||||
let finalize = t_finalize.unwrap_or_default();
|
||||
// update order to delivered if success
|
||||
let _ = tx.send(finalize.vendor_update_success);
|
||||
ctx.request_repaint();
|
||||
|
@ -2453,7 +2504,8 @@ fn release_txset(contact: String, orid: String, ctx: egui::Context, tx: Sender<b
|
|||
fn upload_dinfo_req(dinfo: String, orid: String, ctx: egui::Context, tx: Sender<bool>) {
|
||||
tokio::spawn(async move {
|
||||
log::info!("async upload_dinfo_req");
|
||||
let dinfo = order::upload_delivery_info(&orid, &dinfo).await;
|
||||
let r_dinfo = order::upload_delivery_info(&orid, &dinfo).await;
|
||||
let dinfo = r_dinfo.unwrap_or_default();
|
||||
let _ = tx.send(!dinfo.orid.is_empty());
|
||||
ctx.request_repaint();
|
||||
});
|
||||
|
@ -2492,7 +2544,8 @@ fn create_dispute_req(
|
|||
tx_set: transfer.result.multisig_txset,
|
||||
..Default::default()
|
||||
};
|
||||
let res = dispute::trigger_dispute_request(&a_contact, &dispute).await;
|
||||
let t_res = dispute::trigger_dispute_request(&a_contact, &dispute).await;
|
||||
let res = t_res.unwrap_or_default();
|
||||
if res.created != 0 {
|
||||
// cancel the order and write the dispute to the db
|
||||
let wallet_password = std::env::var(neveko_core::MONERO_WALLET_PASSWORD)
|
||||
|
@ -2500,9 +2553,9 @@ fn create_dispute_req(
|
|||
monero::open_wallet(&String::from(neveko_core::APP_NAME), &wallet_password).await;
|
||||
let pre_sign = monero::sign(String::from(&d_orid)).await;
|
||||
monero::close_wallet(&String::from(neveko_core::APP_NAME), &wallet_password).await;
|
||||
order::cancel_order(&d_orid, &pre_sign.result.signature).await;
|
||||
let _ = order::cancel_order(&d_orid, &pre_sign.result.signature).await;
|
||||
let j_dispute = utils::dispute_to_json(&res);
|
||||
dispute::create(j_dispute);
|
||||
let _ = dispute::create(j_dispute);
|
||||
let _ = tx.send(res);
|
||||
ctx.request_repaint();
|
||||
}
|
||||
|
@ -2512,7 +2565,7 @@ fn create_dispute_req(
|
|||
fn cipher_req(cid: String, m: String, e: Option<String>, tx: Sender<String>, ctx: egui::Context) {
|
||||
tokio::spawn(async move {
|
||||
log::info!("async decipher_req");
|
||||
let contact = contact::find(&cid);
|
||||
let contact = contact::find(&cid).unwrap_or_default();
|
||||
let ciphered = neveko25519::cipher(&contact.nmpk, m, e).await;
|
||||
let _ = tx.send(ciphered);
|
||||
ctx.request_repaint();
|
||||
|
|
|
@ -66,13 +66,14 @@ impl eframe::App for SettingsApp {
|
|||
|
||||
// TODO: don't open the database in the GUI
|
||||
|
||||
let s = db::DatabaseEnvironment::open(&utils::get_release_env().value()).unwrap();
|
||||
let s = db::DatabaseEnvironment::open().unwrap();
|
||||
let k = CREDENTIAL_KEY;
|
||||
db::DatabaseEnvironment::delete(&s.env, &s.handle, &k);
|
||||
let _ = db::DatabaseEnvironment::delete(&s.env, &s.handle.unwrap(), k.as_bytes()).unwrap();
|
||||
let mut hasher = Sha512::new();
|
||||
hasher.update(self.credential.clone());
|
||||
let result = hasher.finalize();
|
||||
db::write_chunks(&s.env, &s.handle, &k, &hex::encode(&result[..]));
|
||||
let s = db::DatabaseEnvironment::open().unwrap();
|
||||
db::write_chunks(&s.env, &s.handle.unwrap(), k.as_bytes(), hex::encode(&result[..]).as_bytes()).unwrap();
|
||||
// update wallet rpc
|
||||
change_wallet_password(
|
||||
self.change_wallet_password_tx.clone(),
|
||||
|
|
|
@ -54,8 +54,8 @@ impl eframe::App for LoginApp {
|
|||
let mut hasher = Sha512::new();
|
||||
hasher.update(self.credential.clone());
|
||||
let result = hasher.finalize();
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
db::DatabaseEnvironment::write(&s.env, &s.handle, k, &hex::encode(&result[..]));
|
||||
let s = db::DatabaseEnvironment::open().unwrap();
|
||||
db::write_chunks(&s.env, &s.handle.unwrap(), k.as_bytes(), hex::encode(&result[..]).as_bytes()).unwrap();
|
||||
self.credential = String::new();
|
||||
}
|
||||
});
|
||||
|
|
|
@ -236,8 +236,12 @@ impl WrapApp {
|
|||
ctx.set_pixels_per_point(1.5);
|
||||
// initial cred check, is there a better way to do this?
|
||||
if !self.state.is_cred_set {
|
||||
let s = db::DatabaseEnvironment::open(&utils::get_release_env().value()).unwrap();
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, crate::CREDENTIAL_KEY);
|
||||
let s = db::DatabaseEnvironment::open().unwrap();
|
||||
let r = db::DatabaseEnvironment::read(
|
||||
&s.env,
|
||||
&s.handle.unwrap(),
|
||||
&crate::CREDENTIAL_KEY.as_bytes().to_vec(),
|
||||
).unwrap();
|
||||
if !r.is_empty() {
|
||||
self.state.is_cred_set = true;
|
||||
self.state.is_checking_cred = false;
|
||||
|
@ -308,8 +312,12 @@ impl WrapApp {
|
|||
loop {
|
||||
log::debug!("check for cred");
|
||||
tokio::time::sleep(std::time::Duration::from_secs(5)).await;
|
||||
let s = db::DatabaseEnvironment::open(&utils::get_release_env().value()).unwrap();
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, crate::CREDENTIAL_KEY);
|
||||
let s = db::DatabaseEnvironment::open().unwrap();
|
||||
let r = db::DatabaseEnvironment::read(
|
||||
&s.env,
|
||||
&s.handle.unwrap(),
|
||||
&crate::CREDENTIAL_KEY.as_bytes().to_vec()
|
||||
).unwrap();
|
||||
if r.is_empty() {
|
||||
log::debug!("credential not found");
|
||||
let _ = tx.send(false);
|
||||
|
|
|
@ -19,15 +19,15 @@ pub async fn create_product(
|
|||
req_product: Json<models::Product>,
|
||||
_token: auth::BearerToken,
|
||||
) -> Custom<Json<models::Product>> {
|
||||
let m_product: models::Product = product::create(req_product);
|
||||
Custom(Status::Created, Json(m_product))
|
||||
let m_product = product::create(req_product);
|
||||
Custom(Status::Created, Json(m_product.unwrap_or_default()))
|
||||
}
|
||||
|
||||
/// Get a product by passing id
|
||||
#[get("/<pid>")]
|
||||
pub async fn get_product(pid: String, _token: auth::BearerToken) -> Custom<Json<models::Product>> {
|
||||
let m_product: models::Product = product::find(&pid);
|
||||
Custom(Status::Ok, Json(m_product))
|
||||
let m_product= product::find(&pid);
|
||||
Custom(Status::Ok, Json(m_product.unwrap_or_default()))
|
||||
}
|
||||
|
||||
/// Update product information
|
||||
|
@ -36,29 +36,29 @@ pub async fn update_product(
|
|||
product: Json<models::Product>,
|
||||
_token: auth::BearerToken,
|
||||
) -> Custom<Json<models::Product>> {
|
||||
let m_product: models::Product = product::modify(product);
|
||||
Custom(Status::Ok, Json(m_product))
|
||||
let m_product = product::modify(product);
|
||||
Custom(Status::Ok, Json(m_product.unwrap_or_default()))
|
||||
}
|
||||
|
||||
/// Return all products
|
||||
#[get("/")]
|
||||
pub async fn get_products(_token: auth::BearerToken) -> Custom<Json<Vec<models::Product>>> {
|
||||
let m_products: Vec<models::Product> = product::find_all();
|
||||
Custom(Status::Ok, Json(m_products))
|
||||
let m_products = product::find_all();
|
||||
Custom(Status::Ok, Json(m_products.unwrap_or_default()))
|
||||
}
|
||||
|
||||
/// Get a order by passing id
|
||||
#[get("/<orid>")]
|
||||
pub async fn get_order(orid: String, _token: auth::BearerToken) -> Custom<Json<models::Order>> {
|
||||
let m_order: models::Order = order::find(&orid);
|
||||
Custom(Status::Ok, Json(m_order))
|
||||
let m_order = order::find(&orid);
|
||||
Custom(Status::Ok, Json(m_order.unwrap_or_default()))
|
||||
}
|
||||
|
||||
/// Get all orders
|
||||
#[get("/")]
|
||||
pub async fn get_orders(_token: auth::BearerToken) -> Custom<Json<Vec<models::Order>>> {
|
||||
let m_orders: Vec<models::Order> = order::find_all();
|
||||
Custom(Status::Ok, Json(m_orders))
|
||||
let m_orders = order::find_all();
|
||||
Custom(Status::Ok, Json(m_orders.unwrap_or_default()))
|
||||
}
|
||||
|
||||
/// Update order information
|
||||
|
@ -67,8 +67,8 @@ pub async fn update_order(
|
|||
order: Json<models::Order>,
|
||||
_token: auth::BearerToken,
|
||||
) -> Custom<Json<models::Order>> {
|
||||
let m_order: models::Order = order::modify(order);
|
||||
Custom(Status::Ok, Json(m_order))
|
||||
let m_order = order::modify(order);
|
||||
Custom(Status::Ok, Json(m_order.unwrap_or_default()))
|
||||
}
|
||||
|
||||
/// Create a dispute
|
||||
|
@ -77,15 +77,15 @@ pub async fn create_dispute(
|
|||
dispute: Json<models::Dispute>,
|
||||
_token: auth::BearerToken,
|
||||
) -> Custom<Json<models::Dispute>> {
|
||||
let m_dispute: models::Dispute = dispute::create(dispute);
|
||||
Custom(Status::Ok, Json(m_dispute))
|
||||
let m_dispute = dispute::create(dispute);
|
||||
Custom(Status::Ok, Json(m_dispute.unwrap_or_default()))
|
||||
}
|
||||
|
||||
/// Fetch a dispute
|
||||
#[get("/<did>")]
|
||||
pub async fn get_dispute(_token: auth::BearerToken, did: String) -> Custom<Json<models::Dispute>> {
|
||||
let m_dispute: models::Dispute = dispute::find(&did);
|
||||
Custom(Status::Ok, Json(m_dispute))
|
||||
let m_dispute = dispute::find(&did);
|
||||
Custom(Status::Ok, Json(m_dispute.unwrap_or_default()))
|
||||
}
|
||||
|
||||
/// Sign and submit multisig
|
||||
|
@ -113,12 +113,12 @@ pub async fn upload_delivery_info(
|
|||
r_data: Json<reqres::FinalizeOrderResponse>,
|
||||
_token: auth::BearerToken,
|
||||
) -> Custom<Json<reqres::FinalizeOrderResponse>> {
|
||||
let upload: reqres::FinalizeOrderResponse =
|
||||
order::upload_delivery_info(&orid, &r_data.delivery_info).await;
|
||||
if upload.delivery_info.is_empty() {
|
||||
let upload = order::upload_delivery_info(&orid, &r_data.delivery_info).await;
|
||||
let u_upload = upload.unwrap_or_default();
|
||||
if u_upload.delivery_info.is_empty() {
|
||||
return Custom(Status::BadRequest, Json(Default::default()));
|
||||
}
|
||||
Custom(Status::Ok, Json(upload))
|
||||
Custom(Status::Ok, Json(u_upload))
|
||||
}
|
||||
|
||||
/// toggle vendor mode
|
||||
|
@ -126,7 +126,7 @@ pub async fn upload_delivery_info(
|
|||
pub async fn toggle_vendor_mode(
|
||||
_token: auth::BearerToken,
|
||||
) -> Custom<Json<reqres::VendorModeResponse>> {
|
||||
let mode = utils::toggle_vendor_enabled();
|
||||
let mode = utils::toggle_vendor_enabled().unwrap_or_default();
|
||||
Custom(Status::Ok, Json(reqres::VendorModeResponse { mode }))
|
||||
}
|
||||
// END JSON APIs
|
||||
|
|
|
@ -29,23 +29,23 @@ pub async fn send_message(
|
|||
} else {
|
||||
message::MessageType::Normal
|
||||
};
|
||||
let res: Message = message::create(m_req, token.get_jwp(), m_type).await;
|
||||
Custom(Status::Ok, Json(res))
|
||||
let res = message::create(m_req, token.get_jwp(), m_type).await;
|
||||
Custom(Status::Ok, Json(res.unwrap_or_default()))
|
||||
}
|
||||
|
||||
/// Return all messages
|
||||
#[get("/")]
|
||||
pub async fn get_messages(_token: auth::BearerToken) -> Custom<Json<Vec<Message>>> {
|
||||
let messages = message::find_all();
|
||||
Custom(Status::Ok, Json(messages))
|
||||
Custom(Status::Ok, Json(messages.unwrap_or_default()))
|
||||
}
|
||||
|
||||
/// Delete a message by mid
|
||||
#[delete("/<mid>")]
|
||||
pub async fn remove_message(mid: String, _token: auth::BearerToken) -> Custom<Json<Vec<Message>>> {
|
||||
message::delete(&mid);
|
||||
let _ = message::delete(&mid);
|
||||
let messages = message::find_all();
|
||||
Custom(Status::Ok, Json(messages))
|
||||
Custom(Status::Ok, Json(messages.unwrap_or_default()))
|
||||
}
|
||||
|
||||
/// decipher a message body
|
||||
|
@ -55,5 +55,5 @@ pub async fn decipher(
|
|||
_token: auth::BearerToken,
|
||||
) -> Custom<Json<reqres::DecipheredMessageBody>> {
|
||||
let d_message = message::decipher_body(mid).await;
|
||||
Custom(Status::Ok, Json(d_message))
|
||||
}
|
||||
Custom(Status::Ok, Json(d_message.unwrap_or_default()))
|
||||
}
|
|
@ -44,8 +44,8 @@ pub async fn get_i2p_status() -> Custom<Json<i2p::HttpProxyStatus>> {
|
|||
/// Protected: false
|
||||
#[get("/")]
|
||||
pub async fn share_contact_info() -> Custom<Json<models::Contact>> {
|
||||
let info: models::Contact = contact::share().await;
|
||||
Custom(Status::Ok, Json(info))
|
||||
let info = contact::share().await;
|
||||
Custom(Status::Ok, Json(info.unwrap_or_default()))
|
||||
}
|
||||
|
||||
/// Recieve messages here
|
||||
|
@ -56,7 +56,7 @@ pub async fn rx_message(
|
|||
_jwp: proof::PaymentProof,
|
||||
message: Json<models::Message>,
|
||||
) -> Custom<Json<models::Message>> {
|
||||
message::rx(message).await;
|
||||
let _ = message::rx(message).await;
|
||||
Custom(Status::Ok, Json(Default::default()))
|
||||
}
|
||||
|
||||
|
@ -84,8 +84,8 @@ pub async fn gen_jwp(proof: Json<proof::TxProof>) -> Custom<Json<reqres::Jwp>> {
|
|||
/// Get a product by passing id
|
||||
#[get("/<pid>")]
|
||||
pub async fn get_product(pid: String, _jwp: proof::PaymentProof) -> Custom<Json<models::Product>> {
|
||||
let m_product: models::Product = product::find(&pid);
|
||||
Custom(Status::Ok, Json(m_product))
|
||||
let m_product = product::find(&pid);
|
||||
Custom(Status::Ok, Json(m_product.unwrap_or_default()))
|
||||
}
|
||||
|
||||
/// Get all products
|
||||
|
@ -93,7 +93,7 @@ pub async fn get_product(pid: String, _jwp: proof::PaymentProof) -> Custom<Json<
|
|||
/// Protected: true
|
||||
#[get("/products")]
|
||||
pub async fn get_products(_jwp: proof::PaymentProof) -> Custom<Json<Vec<models::Product>>> {
|
||||
let m_products: Vec<models::Product> = product::find_all();
|
||||
let m_products: Vec<models::Product> = product::find_all().unwrap_or_default();
|
||||
Custom(Status::Ok, Json(m_products))
|
||||
}
|
||||
|
||||
|
@ -105,8 +105,8 @@ pub async fn create_order(
|
|||
r_order: Json<reqres::OrderRequest>,
|
||||
_jwp: proof::PaymentProof,
|
||||
) -> Custom<Json<models::Order>> {
|
||||
let m_order: models::Order = order::create(r_order).await;
|
||||
Custom(Status::Created, Json(m_order))
|
||||
let m_order = order::create(r_order).await;
|
||||
Custom(Status::Created, Json(m_order.unwrap_or_default()))
|
||||
}
|
||||
|
||||
/// Customer order retreival. Must send `signature`
|
||||
|
@ -120,7 +120,8 @@ pub async fn retrieve_order(
|
|||
signature: String,
|
||||
_jwp: proof::PaymentProof,
|
||||
) -> Custom<Json<models::Order>> {
|
||||
let m_order = order::secure_retrieval(&orid, &signature).await;
|
||||
let r_m_order = order::secure_retrieval(&orid, &signature).await;
|
||||
let m_order = r_m_order.unwrap_or_default();
|
||||
if m_order.cid.is_empty() {
|
||||
return Custom(Status::BadRequest, Json(Default::default()));
|
||||
}
|
||||
|
@ -141,15 +142,15 @@ pub async fn get_multisig_info(
|
|||
if r_info.init_adjudicator {
|
||||
order::init_adjudicator_wallet(&r_info.orid).await;
|
||||
}
|
||||
message::send_prepare_info(&r_info.orid, &r_info.contact).await;
|
||||
let _ = message::send_prepare_info(&r_info.orid, &r_info.contact).await;
|
||||
} else if r_info.msig_type == *message::MAKE_MSIG {
|
||||
message::send_make_info(&r_info.orid, &r_info.contact, info).await;
|
||||
let _ = message::send_make_info(&r_info.orid, &r_info.contact, info).await;
|
||||
} else if r_info.msig_type == *message::EXPORT_MSIG {
|
||||
message::send_export_info(&r_info.orid, &r_info.contact).await;
|
||||
let _ = message::send_export_info(&r_info.orid, &r_info.contact).await;
|
||||
} else if r_info.msig_type == *message::IMPORT_MSIG {
|
||||
message::send_import_info(&r_info.orid, &r_info.info).await;
|
||||
let _ = message::send_import_info(&r_info.orid, &r_info.info).await;
|
||||
} else {
|
||||
message::send_exchange_info(&r_info.orid, &r_info.contact, info, r_info.kex_init).await;
|
||||
let _ = message::send_exchange_info(&r_info.orid, &r_info.contact, info, r_info.kex_init).await;
|
||||
}
|
||||
Custom(Status::Ok, Json(Default::default()))
|
||||
}
|
||||
|
@ -162,7 +163,7 @@ pub async fn rx_multisig_message(
|
|||
_jwp: proof::PaymentProof,
|
||||
message: Json<models::Message>,
|
||||
) -> Custom<Json<models::Message>> {
|
||||
message::rx_multisig(message).await;
|
||||
let _ = message::rx_multisig(message).await;
|
||||
Custom(Status::Ok, Json(Default::default()))
|
||||
}
|
||||
|
||||
|
@ -182,7 +183,8 @@ pub async fn request_shipment(
|
|||
orid: String,
|
||||
_jwp: proof::PaymentProof,
|
||||
) -> Custom<Json<reqres::FinalizeOrderResponse>> {
|
||||
let finalize: reqres::FinalizeOrderResponse = order::validate_order_for_ship(&orid).await;
|
||||
let r_finalize = order::validate_order_for_ship(&orid).await;
|
||||
let finalize = r_finalize.unwrap_or_default();
|
||||
if finalize.delivery_info.is_empty() {
|
||||
return Custom(Status::BadRequest, Json(Default::default()));
|
||||
}
|
||||
|
@ -204,7 +206,8 @@ pub async fn trigger_nasr(
|
|||
vendor: String,
|
||||
_jwp: proof::PaymentProof,
|
||||
) -> Custom<Json<models::Order>> {
|
||||
let order: models::Order = order::d_trigger_ship_request(&vendor, &orid).await;
|
||||
let r_order = order::d_trigger_ship_request(&vendor, &orid).await;
|
||||
let order = r_order.unwrap_or_default();
|
||||
if order.orid.is_empty() {
|
||||
return Custom(Status::BadRequest, Json(Default::default()));
|
||||
}
|
||||
|
@ -222,7 +225,8 @@ pub async fn cancel_order(
|
|||
signature: String,
|
||||
_jwp: proof::PaymentProof,
|
||||
) -> Custom<Json<models::Order>> {
|
||||
let m_order = order::cancel_order(&orid, &signature).await;
|
||||
let r_m_order = order::cancel_order(&orid, &signature).await;
|
||||
let m_order = r_m_order.unwrap_or_default();
|
||||
if m_order.cid.is_empty() {
|
||||
return Custom(Status::BadRequest, Json(Default::default()));
|
||||
}
|
||||
|
@ -239,7 +243,8 @@ pub async fn finalize_order(
|
|||
orid: String,
|
||||
_jwp: proof::PaymentProof,
|
||||
) -> Custom<Json<reqres::FinalizeOrderResponse>> {
|
||||
let finalize = order::finalize_order(&orid).await;
|
||||
let r_finalize = order::finalize_order(&orid).await;
|
||||
let finalize = r_finalize.unwrap_or_default();
|
||||
if !finalize.vendor_update_success {
|
||||
return Custom(Status::BadRequest, Json(Default::default()));
|
||||
}
|
||||
|
@ -252,7 +257,8 @@ pub async fn create_dispute(
|
|||
dispute: Json<models::Dispute>,
|
||||
_jwp: proof::PaymentProof,
|
||||
) -> Custom<Json<models::Dispute>> {
|
||||
let m_dispute: models::Dispute = dispute::create(dispute);
|
||||
let r_m_dispute = dispute::create(dispute);
|
||||
let m_dispute = r_m_dispute.unwrap_or_default();
|
||||
Custom(Status::Ok, Json(m_dispute))
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ async fn rocket() -> _ {
|
|||
..rocket::Config::debug_default()
|
||||
};
|
||||
env_logger::init();
|
||||
utils::start_up().await;
|
||||
let _ = utils::start_up().await;
|
||||
rocket::custom(&config)
|
||||
.register(
|
||||
"/",
|
||||
|
|
Loading…
Reference in a new issue