mirror of
https://github.com/creating2morrow/neveko.git
synced 2024-12-22 11:39:22 +00:00
serialization fixes
This commit is contained in:
parent
a4cd1d3624
commit
eb5c0b370d
31 changed files with 996 additions and 1861 deletions
174
Cargo.lock
generated
174
Cargo.lock
generated
|
@ -567,16 +567,6 @@ dependencies = [
|
|||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.3"
|
||||
|
@ -1117,7 +1107,7 @@ dependencies = [
|
|||
"libc 0.2.153",
|
||||
"log",
|
||||
"rustversion",
|
||||
"windows",
|
||||
"windows 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1418,7 +1408,7 @@ dependencies = [
|
|||
"iana-time-zone-haiku",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"windows",
|
||||
"windows 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1946,6 +1936,8 @@ dependencies = [
|
|||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"sysinfo",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
|
@ -2035,6 +2027,15 @@ dependencies = [
|
|||
"minimal-lexical",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ntapi"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nu-ansi-term"
|
||||
version = "0.46.0"
|
||||
|
@ -2494,9 +2495,9 @@ checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9"
|
|||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.7.0"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b"
|
||||
checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
|
||||
dependencies = [
|
||||
"either",
|
||||
"rayon-core",
|
||||
|
@ -2504,14 +2505,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.11.0"
|
||||
version = "1.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d"
|
||||
checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"crossbeam-deque",
|
||||
"crossbeam-utils",
|
||||
"num_cpus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3095,6 +3094,20 @@ version = "0.1.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
|
||||
|
||||
[[package]]
|
||||
name = "sysinfo"
|
||||
version = "0.31.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "355dbe4f8799b304b05e1b0f05fc59b2a18d36645cf169607da45bde2f69a1be"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc 0.2.153",
|
||||
"memchr",
|
||||
"ntapi",
|
||||
"rayon",
|
||||
"windows 0.57.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "system-configuration"
|
||||
version = "0.5.1"
|
||||
|
@ -3150,18 +3163,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.40"
|
||||
version = "1.0.63"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac"
|
||||
checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.40"
|
||||
version = "1.0.63"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
|
||||
checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -3817,6 +3830,59 @@ dependencies = [
|
|||
"windows-targets 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143"
|
||||
dependencies = [
|
||||
"windows-core",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d"
|
||||
dependencies = [
|
||||
"windows-implement",
|
||||
"windows-interface",
|
||||
"windows-result",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-implement"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-interface"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-result"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.42.0"
|
||||
|
@ -3880,6 +3946,22 @@ dependencies = [
|
|||
"windows_x86_64_msvc 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.52.6",
|
||||
"windows_aarch64_msvc 0.52.6",
|
||||
"windows_i686_gnu 0.52.6",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc 0.52.6",
|
||||
"windows_x86_64_gnu 0.52.6",
|
||||
"windows_x86_64_gnullvm 0.52.6",
|
||||
"windows_x86_64_msvc 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.42.2"
|
||||
|
@ -3892,6 +3974,12 @@ version = "0.48.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.42.2"
|
||||
|
@ -3904,6 +3992,12 @@ version = "0.48.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.42.2"
|
||||
|
@ -3916,6 +4010,18 @@ version = "0.48.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.42.2"
|
||||
|
@ -3928,6 +4034,12 @@ version = "0.48.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.42.2"
|
||||
|
@ -3940,6 +4052,12 @@ version = "0.48.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.42.2"
|
||||
|
@ -3952,6 +4070,12 @@ version = "0.48.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.42.2"
|
||||
|
@ -3964,6 +4088,12 @@ version = "0.48.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "winit"
|
||||
version = "0.28.6"
|
||||
|
|
|
@ -25,7 +25,7 @@ pub async fn add_contact(
|
|||
_token: auth::BearerToken,
|
||||
) -> Custom<Json<Contact>> {
|
||||
let res_contact = contact::create(&req_contact).await;
|
||||
if res_contact.cid == utils::empty_string() {
|
||||
if res_contact.cid.is_empty() {
|
||||
return Custom(Status::BadRequest, Json(Default::default()));
|
||||
}
|
||||
Custom(Status::Ok, Json(res_contact))
|
||||
|
|
|
@ -28,4 +28,6 @@ schedule_recv = "0.1.0"
|
|||
sha2 = "0.10.6"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0.94"
|
||||
sysinfo = "0.31.2"
|
||||
thiserror = "1.0.63"
|
||||
tokio = "1.25.0"
|
||||
|
|
|
@ -34,13 +34,6 @@ pub struct Args {
|
|||
default_value = "/home/user/.bitmonero"
|
||||
)]
|
||||
pub monero_blockchain_dir: String,
|
||||
/// Absolute path to i2p zero
|
||||
#[arg(
|
||||
long,
|
||||
help = "Absolute path to i2p-zero directroy",
|
||||
default_value = "/home/user/i2p-zero-linux.v1.21"
|
||||
)]
|
||||
pub i2p_zero_dir: String,
|
||||
/// Monero RPC daemon host
|
||||
#[arg(
|
||||
long,
|
||||
|
|
|
@ -10,6 +10,7 @@ use crate::{
|
|||
utils,
|
||||
};
|
||||
use clap::Parser;
|
||||
use kn0sys_lmdb_rs::MdbError;
|
||||
use log::{
|
||||
debug,
|
||||
error,
|
||||
|
@ -32,7 +33,7 @@ use sha2::Sha384;
|
|||
use std::collections::BTreeMap;
|
||||
|
||||
/// Create authorization data to sign and expiration
|
||||
pub fn create(address: &String) -> Authorization {
|
||||
pub fn create(address: &String) -> Result<Authorization, MdbError> {
|
||||
info!("creating auth");
|
||||
let aid: String = format!("{}{}", crate::AUTH_DB_KEY, utils::generate_rnd());
|
||||
let rnd: String = utils::generate_rnd();
|
||||
|
@ -41,32 +42,35 @@ pub fn create(address: &String) -> Authorization {
|
|||
let new_auth = Authorization {
|
||||
aid,
|
||||
created,
|
||||
uid: utils::empty_string(),
|
||||
uid: String::new(),
|
||||
rnd,
|
||||
token,
|
||||
xmr_address: String::from(address),
|
||||
};
|
||||
let s = db::Interface::open();
|
||||
let env = utils::get_release_env();
|
||||
let s = db::DatabaseEnvironment::open(&env.value())?;
|
||||
debug!("insert auth: {:?}", &new_auth);
|
||||
let k = &new_auth.aid;
|
||||
db::Interface::write(&s.env, &s.handle, k, &Authorization::to_db(&new_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);
|
||||
Ok(new_auth)
|
||||
}
|
||||
|
||||
/// Authorization lookup for recurring requests
|
||||
pub fn find(aid: &String) -> Authorization {
|
||||
pub fn find(aid: &String) -> Result<Authorization, MdbError> {
|
||||
info!("searching for auth: {}", aid);
|
||||
let s = db::Interface::open();
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(aid));
|
||||
debug!("auth read: {}", r);
|
||||
if r == utils::empty_string() {
|
||||
return Default::default();
|
||||
let env = utils::get_release_env();
|
||||
let s = db::DatabaseEnvironment::open(&env.value())?;
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &aid.as_bytes().to_vec())?;
|
||||
if r.is_empty() {
|
||||
return Err(MdbError::NotFound);
|
||||
}
|
||||
Authorization::from_db(String::from(aid), r)
|
||||
let result: Authorization = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// Update new authorization creation time
|
||||
fn update_expiration(f_auth: &Authorization, address: &String) -> Authorization {
|
||||
fn update_expiration(f_auth: &Authorization, address: &String) -> Result<Authorization, MdbError> {
|
||||
info!("modify auth expiration");
|
||||
let data = utils::generate_rnd();
|
||||
let time: i64 = chrono::offset::Utc::now().timestamp();
|
||||
|
@ -77,27 +81,26 @@ fn update_expiration(f_auth: &Authorization, address: &String) -> Authorization
|
|||
data,
|
||||
create_token(String::from(address), time),
|
||||
);
|
||||
let s = db::Interface::open();
|
||||
db::Interface::delete(&s.env, &s.handle, &u_auth.aid);
|
||||
db::Interface::write(
|
||||
&s.env,
|
||||
&s.handle,
|
||||
&u_auth.aid,
|
||||
&Authorization::to_db(&u_auth),
|
||||
);
|
||||
u_auth
|
||||
let env = utils::get_release_env();
|
||||
let s = db::DatabaseEnvironment::open(&env.value())?;
|
||||
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(&env.value())?;
|
||||
db::write_chunks(&s.env, &s.handle?, k, &v);
|
||||
Ok(u_auth)
|
||||
}
|
||||
|
||||
/// Performs the signature verfication against stored auth
|
||||
pub async fn verify_login(aid: String, uid: String, signature: String) -> Authorization {
|
||||
pub async fn verify_login(aid: String, uid: String, signature: String) -> Result<Authorization, MdbError> {
|
||||
let wallet_name = String::from(crate::APP_NAME);
|
||||
let wallet_password =
|
||||
std::env::var(crate::MONERO_WALLET_PASSWORD).unwrap_or(String::from("password"));
|
||||
monero::open_wallet(&wallet_name, &wallet_password).await;
|
||||
let m_address: reqres::XmrRpcAddressResponse = monero::get_address().await;
|
||||
let address = m_address.result.address;
|
||||
let f_auth: Authorization = find(&aid);
|
||||
if f_auth.xmr_address == utils::empty_string() {
|
||||
let f_auth: Authorization = find(&aid)?;
|
||||
if f_auth.xmr_address.is_empty() {
|
||||
error!("auth not found");
|
||||
monero::close_wallet(&wallet_name, &wallet_password).await;
|
||||
return create(&address);
|
||||
|
@ -113,51 +116,49 @@ pub async fn verify_login(aid: String, uid: String, signature: String) -> Author
|
|||
if sig_address == utils::ApplicationErrors::LoginError.value() {
|
||||
error!("signature validation failed");
|
||||
monero::close_wallet(&wallet_name, &wallet_password).await;
|
||||
return f_auth;
|
||||
return Ok(f_auth);
|
||||
}
|
||||
let f_user: User = user::find(&uid);
|
||||
if f_user.xmr_address == utils::empty_string() {
|
||||
let f_user: User = user::find(&uid)?;
|
||||
if f_user.xmr_address.is_empty() {
|
||||
info!("creating new user");
|
||||
let u: User = user::create(&address);
|
||||
let u: User = user::create(&address)?;
|
||||
// update auth with uid
|
||||
let u_auth = Authorization::update_uid(f_auth, String::from(&u.uid));
|
||||
let s = db::Interface::open();
|
||||
db::Interface::delete(&s.env, &s.handle, &u_auth.aid);
|
||||
db::Interface::write(
|
||||
&s.env,
|
||||
&s.handle,
|
||||
&u_auth.aid,
|
||||
&Authorization::to_db(&u_auth),
|
||||
);
|
||||
let env = utils::get_release_env();
|
||||
let s = db::DatabaseEnvironment::open(&env.value())?;
|
||||
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(&env.value())?;
|
||||
db::write_chunks(&s.env, &s.handle?, u_auth.aid.as_bytes(), &v);
|
||||
monero::close_wallet(&wallet_name, &wallet_password).await;
|
||||
u_auth
|
||||
} else if f_user.xmr_address != utils::empty_string() {
|
||||
Ok(u_auth)
|
||||
} else if !f_user.xmr_address.is_empty() {
|
||||
info!("returning user");
|
||||
let m_access = verify_access(&address, &signature).await;
|
||||
let m_access = verify_access(&address, &signature).await?;
|
||||
if !m_access {
|
||||
monero::close_wallet(&wallet_name, &wallet_password).await;
|
||||
return Default::default();
|
||||
return Ok(Default::default());
|
||||
}
|
||||
monero::close_wallet(&wallet_name, &wallet_password).await;
|
||||
return f_auth;
|
||||
return Ok(f_auth);
|
||||
} else {
|
||||
error!("error creating user");
|
||||
monero::close_wallet(&wallet_name, &wallet_password).await;
|
||||
return Default::default();
|
||||
return Ok(Default::default());
|
||||
}
|
||||
}
|
||||
|
||||
/// Called during auth flow to update data to sign and expiration
|
||||
async fn verify_access(address: &String, signature: &String) -> bool {
|
||||
async fn verify_access(address: &String, signature: &String) -> Result<bool, MdbError> {
|
||||
// look up auth for address
|
||||
let f_auth: Authorization = find(address);
|
||||
if f_auth.xmr_address != utils::empty_string() {
|
||||
let f_auth: Authorization = find(address)?;
|
||||
if !f_auth.xmr_address.is_empty() {
|
||||
// check expiration, generate new data to sign if necessary
|
||||
let now: i64 = chrono::offset::Utc::now().timestamp();
|
||||
let expiration = get_auth_expiration();
|
||||
if now > f_auth.created + expiration {
|
||||
update_expiration(&f_auth, address);
|
||||
return false;
|
||||
return Ok(false);
|
||||
}
|
||||
}
|
||||
// verify signature on the data if not expired
|
||||
|
@ -171,10 +172,10 @@ async fn verify_access(address: &String, signature: &String) -> bool {
|
|||
};
|
||||
if sig_address == utils::ApplicationErrors::LoginError.value() {
|
||||
debug!("signing failed");
|
||||
return false;
|
||||
return Ok(false);
|
||||
}
|
||||
info!("auth verified");
|
||||
true
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
/// get the auth expiration command line configuration
|
||||
|
@ -224,7 +225,7 @@ impl<'r> FromRequest<'r> for BearerToken {
|
|||
let env = utils::get_release_env();
|
||||
let dev = utils::ReleaseEnvironment::Development;
|
||||
if env == dev {
|
||||
return Outcome::Success(BearerToken(utils::empty_string()));
|
||||
return Outcome::Success(BearerToken(String::new()));
|
||||
}
|
||||
let token = request.headers().get_one("token");
|
||||
let wallet_name = String::from(crate::APP_NAME);
|
||||
|
@ -281,17 +282,17 @@ impl<'r> FromRequest<'r> for BearerToken {
|
|||
mod tests {
|
||||
use super::*;
|
||||
|
||||
async fn find_test_auth(k: &String) -> Authorization {
|
||||
async fn find_test_auth(k: &String) -> Result<Authorization, MdbError> {
|
||||
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
|
||||
let s: db::Interface = db::Interface::async_open().await;
|
||||
let v = db::Interface::async_read(&s.env, &s.handle, k).await;
|
||||
let s: db::Interface = db::DatabaseEnvironment::async_open("test").await;
|
||||
let v = db::DatabaseEnvironment::read(&s.env, &s.handle, k).await;
|
||||
Authorization::from_db(String::from(k), v)
|
||||
}
|
||||
|
||||
async fn cleanup(k: &String) {
|
||||
async fn cleanup(k: &String) -> Result<(), MdbError>{
|
||||
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
|
||||
let s = db::Interface::async_open().await;
|
||||
db::Interface::async_delete(&s.env, &s.handle, k).await;
|
||||
let s = db::DatabaseEnvironment::open("test").await?;
|
||||
db::DatabaseEnvironment::delete(&s.env, &s.handle?, k).await;
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -8,6 +8,7 @@ use crate::{
|
|||
reqres,
|
||||
utils,
|
||||
};
|
||||
use kn0sys_lmdb_rs::MdbError;
|
||||
use log::{
|
||||
debug,
|
||||
error,
|
||||
|
@ -21,22 +22,8 @@ pub const NEVEKO_VENDOR_ENABLED: &str = "NEVEKO_VENDOR_ENABLED";
|
|||
pub const NEVEKO_VENDOR_MODE_OFF: &str = "0";
|
||||
pub const NEVEKO_VENDOR_MODE_ON: &str = "1";
|
||||
|
||||
pub enum Prune {
|
||||
Full,
|
||||
Pruned,
|
||||
}
|
||||
|
||||
impl Prune {
|
||||
pub fn value(&self) -> u32 {
|
||||
match *self {
|
||||
Prune::Full => 0,
|
||||
Prune::Pruned => 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new contact
|
||||
pub async fn create(c: &Json<Contact>) -> Contact {
|
||||
pub async fn create(c: &Json<Contact>) -> Result<Contact, MdbError> {
|
||||
let f_cid: String = format!("{}{}", crate::CONTACT_DB_KEY, utils::generate_rnd());
|
||||
info!("creating contact: {}", f_cid);
|
||||
let new_contact = Contact {
|
||||
|
@ -48,80 +35,95 @@ pub async fn create(c: &Json<Contact>) -> Contact {
|
|||
};
|
||||
let is_valid = validate_contact(c).await;
|
||||
if !is_valid {
|
||||
return Default::default();
|
||||
log::error!("invalid contact");
|
||||
return Ok(Default::default());
|
||||
}
|
||||
debug!("insert contact: {:?}", &new_contact);
|
||||
let s = db::Interface::open();
|
||||
let env = utils::get_release_env();
|
||||
let s = db::DatabaseEnvironment::open(&env.value())?;
|
||||
let k = &new_contact.cid;
|
||||
db::Interface::write(&s.env, &s.handle, k, &Contact::to_db(&new_contact));
|
||||
let v = bincode::serialize(&new_contact).unwrap_or_default();
|
||||
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 r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
||||
if r == utils::empty_string() {
|
||||
let str_lk = String::from(list_key);
|
||||
let s = db::DatabaseEnvironment::open(&env.value())?;
|
||||
let lk_bytes = str_lk.as_bytes();
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &lk_bytes.to_vec())?;
|
||||
if r.is_empty() {
|
||||
debug!("creating contact index");
|
||||
}
|
||||
let contact_list = [r, String::from(&f_cid)].join(",");
|
||||
let old: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
let contact_list = [old, String::from(&f_cid)].join(",");
|
||||
debug!(
|
||||
"writing contact index {} for key {}",
|
||||
contact_list, list_key
|
||||
);
|
||||
db::Interface::write(&s.env, &s.handle, &String::from(list_key), &contact_list);
|
||||
new_contact
|
||||
let s = db::DatabaseEnvironment::open(&env.value())?;
|
||||
db::write_chunks(&s.env, &s.handle?, list_key.as_bytes(), &contact_list.as_bytes());
|
||||
Ok(new_contact)
|
||||
}
|
||||
|
||||
/// Contact lookup
|
||||
pub fn find(cid: &String) -> Contact {
|
||||
let s = db::Interface::open();
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(cid));
|
||||
if r == utils::empty_string() {
|
||||
pub fn find(cid: &String) -> Result<Contact, MdbError> {
|
||||
let env = utils::get_release_env();
|
||||
let s = db::DatabaseEnvironment::open(&env.value())?;
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &cid.as_bytes().to_vec())?;
|
||||
if r.is_empty() {
|
||||
error!("contact not found");
|
||||
return Default::default();
|
||||
return Err(MdbError::NotFound);
|
||||
}
|
||||
Contact::from_db(String::from(cid), r)
|
||||
let result: Contact = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// Contact lookup
|
||||
pub fn find_by_i2p_address(i2p_address: &String) -> Contact {
|
||||
let contacts = find_all();
|
||||
pub fn find_by_i2p_address(i2p_address: &String) -> Result<Contact , MdbError> {
|
||||
let contacts = find_all()?;
|
||||
for c in contacts {
|
||||
if c.i2p_address == *i2p_address {
|
||||
return c;
|
||||
return Ok(c);
|
||||
}
|
||||
}
|
||||
Default::default()
|
||||
Err(MdbError::NotFound)
|
||||
}
|
||||
|
||||
/// Contact deletion
|
||||
pub fn delete(cid: &String) {
|
||||
let s = db::Interface::open();
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(cid));
|
||||
if r == utils::empty_string() {
|
||||
pub fn delete(cid: &String) -> Result<(), MdbError> {
|
||||
let env = utils::get_release_env();
|
||||
let s = db::DatabaseEnvironment::open(&env.value())?;
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &cid.as_bytes().to_vec())?;
|
||||
if r.is_empty() {
|
||||
error!("contact not found");
|
||||
return;
|
||||
return Err(MdbError::NotFound);
|
||||
}
|
||||
db::Interface::delete(&s.env, &s.handle, cid);
|
||||
let s = db::DatabaseEnvironment::open(&env.value())?;
|
||||
db::DatabaseEnvironment::delete(&s.env, &s.handle?, cid.as_bytes());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// All contact lookup
|
||||
pub fn find_all() -> Vec<Contact> {
|
||||
pub fn find_all() -> Result<Vec<Contact>, MdbError> {
|
||||
info!("looking up all contacts");
|
||||
let s = db::Interface::open();
|
||||
let env = utils::get_release_env();
|
||||
let s = db::DatabaseEnvironment::open(&env.value())?;
|
||||
let list_key = crate::CONTACT_LIST_DB_KEY;
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
||||
if r == utils::empty_string() {
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &list_key.as_bytes().to_vec())?;
|
||||
if r.is_empty() {
|
||||
error!("contact index not found");
|
||||
return Default::default();
|
||||
return Err(MdbError::NotFound);
|
||||
}
|
||||
let v_cid = r.split(",");
|
||||
let str_r: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
let v_cid = str_r.split(",");
|
||||
let v: Vec<String> = v_cid.map(String::from).collect();
|
||||
let mut contacts: Vec<Contact> = Vec::new();
|
||||
for id in v {
|
||||
if id != utils::empty_string() {
|
||||
let contact: Contact = find(&id);
|
||||
if !id.is_empty() {
|
||||
let contact: Contact = find(&id)?;
|
||||
contacts.push(contact);
|
||||
}
|
||||
}
|
||||
contacts
|
||||
Ok(contacts)
|
||||
}
|
||||
|
||||
async fn validate_contact(j: &Json<Contact>) -> bool {
|
||||
|
@ -140,10 +142,12 @@ async fn validate_contact(j: &Json<Contact>) -> bool {
|
|||
}
|
||||
|
||||
/// Send our information
|
||||
pub async fn share() -> Contact {
|
||||
let s = db::Interface::async_open().await;
|
||||
let r = db::Interface::async_read(&s.env, &s.handle, NEVEKO_VENDOR_ENABLED).await;
|
||||
let is_vendor = r == NEVEKO_VENDOR_MODE_ON;
|
||||
pub async fn share() -> Result<Contact, MdbError> {
|
||||
let env = utils::get_release_env();
|
||||
let s = db::DatabaseEnvironment::open(&env.value())?;
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &NEVEKO_VENDOR_ENABLED.as_bytes().to_vec())?;
|
||||
let str_r: String = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
let is_vendor = str_r == NEVEKO_VENDOR_MODE_ON;
|
||||
let wallet_name = String::from(crate::APP_NAME);
|
||||
let wallet_password =
|
||||
std::env::var(crate::MONERO_WALLET_PASSWORD).unwrap_or(String::from("password"));
|
||||
|
@ -153,22 +157,22 @@ pub async fn share() -> Contact {
|
|||
let nmpk = utils::get_nmpk();
|
||||
let i2p_address = i2p::get_destination(None);
|
||||
let xmr_address = m_address.result.address;
|
||||
Contact {
|
||||
cid: utils::empty_string(),
|
||||
Ok(Contact {
|
||||
cid: String::new(),
|
||||
nmpk,
|
||||
i2p_address,
|
||||
is_vendor,
|
||||
xmr_address,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn exists(from: &String) -> bool {
|
||||
let all = find_all();
|
||||
pub fn exists(from: &String) -> Result<bool, MdbError> {
|
||||
let all = find_all()?;
|
||||
let mut addresses: Vec<String> = Vec::new();
|
||||
for c in all {
|
||||
addresses.push(c.i2p_address);
|
||||
}
|
||||
addresses.contains(from)
|
||||
Ok(addresses.contains(from))
|
||||
}
|
||||
|
||||
/// Get invoice for jwp creation
|
||||
|
@ -228,10 +232,10 @@ pub async fn add_contact_request(contact: String) -> Result<Contact, Box<dyn Err
|
|||
mod tests {
|
||||
use super::*;
|
||||
|
||||
async fn cleanup(k: &String) {
|
||||
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
|
||||
let s = db::Interface::async_open().await;
|
||||
db::Interface::async_delete(&s.env, &s.handle, k).await;
|
||||
fn cleanup(k: &String) {
|
||||
let env = utils::get_release_env();
|
||||
let s = db::DatabaseEnvironment::open(&env.value());
|
||||
db::DatabaseEnvironment::delete(&s.env, &s.handle, k);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -272,8 +276,8 @@ mod tests {
|
|||
..Default::default()
|
||||
};
|
||||
tokio::spawn(async move {
|
||||
let s = db::Interface::async_open().await;
|
||||
db::Interface::async_write(&s.env, &s.handle, k, &Contact::to_db(&expected_contact))
|
||||
let s = db::DatabaseEnvironment::async_open().await;
|
||||
db::DatabaseEnvironment::async_write(&s.env, &s.handle, k, &Contact::to_db(&expected_contact))
|
||||
.await;
|
||||
let actual_contact: Contact = find(&String::from(k));
|
||||
assert_eq!(expected_contact.xmr_address, actual_contact.xmr_address);
|
||||
|
|
|
@ -1,179 +1,214 @@
|
|||
//! Primary LMDB interface for read, write, delete etc.
|
||||
#![deny(missing_docs)]
|
||||
|
||||
//! Logic for interfacing with LMDB.
|
||||
|
||||
extern crate kn0sys_lmdb_rs as lmdb;
|
||||
|
||||
use lmdb::{
|
||||
DbFlags,
|
||||
DbHandle,
|
||||
EnvBuilder,
|
||||
Environment,
|
||||
};
|
||||
use log::{
|
||||
debug,
|
||||
error,
|
||||
info,
|
||||
};
|
||||
use lmdb::*;
|
||||
use log::{error, info};
|
||||
use sysinfo::System;
|
||||
|
||||
use crate::utils;
|
||||
/// Ratio of map size to available memory is 20 percent
|
||||
const MAP_SIZE_MEMORY_RATIO: f32 = 0.2;
|
||||
/// Ratio of chunk size to available memory is 0.2 percent
|
||||
const CHUNK_SIZE_MEMORY_RATIO: f32 = MAP_SIZE_MEMORY_RATIO * 0.01;
|
||||
|
||||
/// LMDB Interface allows access to the env
|
||||
/// The database environment for handling primary database operations.
|
||||
///
|
||||
/// and handle for the write, read and delete
|
||||
///
|
||||
/// functionality.
|
||||
pub struct Interface {
|
||||
/// By default the database will be written to /home/user/.valentinus/{ENV}/lmdb
|
||||
pub struct DatabaseEnvironment {
|
||||
pub env: Environment,
|
||||
pub handle: DbHandle,
|
||||
pub handle: Result<DbHandle, MdbError>,
|
||||
}
|
||||
|
||||
impl Interface {
|
||||
/// Instantiation of ```Environment``` and ```DbHandle```
|
||||
pub fn open() -> Self {
|
||||
info!("excecuting lmdb open");
|
||||
let release_env = utils::get_release_env();
|
||||
let file_path = format!(
|
||||
"/home/{}/.{}/",
|
||||
std::env::var("USER").unwrap_or(String::from("user")),
|
||||
crate::APP_NAME,
|
||||
);
|
||||
let mut env_str: &str = "test-lmdb";
|
||||
if release_env != utils::ReleaseEnvironment::Development {
|
||||
env_str = "lmdb";
|
||||
};
|
||||
let env = EnvBuilder::new()
|
||||
// increase map size for writing the multisig txset
|
||||
.map_size(crate::LMDB_MAPSIZE)
|
||||
.open(format!("{}/{}", file_path, env_str), 0o777)
|
||||
.unwrap_or_else(|_| panic!("could not open LMDB at {}", file_path));
|
||||
let handle = env.get_default_db(DbFlags::empty()).unwrap();
|
||||
Interface { env, handle }
|
||||
}
|
||||
pub async fn async_open() -> Self {
|
||||
info!("excecuting lmdb async open");
|
||||
tokio::time::sleep(std::time::Duration::from_micros(1)).await;
|
||||
self::Interface::open()
|
||||
}
|
||||
/// Write a key-value to LMDB. NEVEKO does not currently support
|
||||
impl DatabaseEnvironment {
|
||||
/// Opens environment in specified path. The map size defaults to 20 percent
|
||||
///
|
||||
/// writing multiple key value pairs.
|
||||
pub fn write(e: &Environment, h: &DbHandle, k: &str, v: &str) {
|
||||
/// of available memory and can be set via the `LMDB_MAP_SIZE` environment variable.
|
||||
///
|
||||
/// The path of the user can be set with `LMDB_USER`.
|
||||
pub fn open(env: &str) -> Result<Self, MdbError> {
|
||||
let s = System::new_all();
|
||||
let default_map_size: u64 =
|
||||
(s.available_memory() as f32 * MAP_SIZE_MEMORY_RATIO).floor() as u64;
|
||||
let env_map_size: u64 = match std::env::var("LMDB_MAP_SIZE") {
|
||||
Err(_) => default_map_size,
|
||||
Ok(size) => size.parse::<u64>().unwrap_or(default_map_size),
|
||||
};
|
||||
info!("setting lmdb map size to: {}", env_map_size);
|
||||
let user: String = match std::env::var("LMDB_USER") {
|
||||
Err(_) => std::env::var("USER").unwrap_or(String::from("user")),
|
||||
Ok(user) => user,
|
||||
};
|
||||
info!("$LMDB_USER={}", user);
|
||||
info!("excecuting lmdb open");
|
||||
let file_path: String = format!("/home/{}/.{}/", user, "valentinus");
|
||||
let env: Environment = EnvBuilder::new()
|
||||
.map_size(env_map_size)
|
||||
.open(format!("{}/{}", file_path, env), 0o777)
|
||||
.unwrap_or_else(|_| panic!("could not open LMDB at {}", file_path));
|
||||
let default: Result<DbHandle, MdbError> = env.get_default_db(DbFlags::empty());
|
||||
if default.is_err() {
|
||||
panic!("could not set db handle")
|
||||
}
|
||||
let handle: DbHandle = default?;
|
||||
Ok(DatabaseEnvironment {
|
||||
env,
|
||||
handle: Ok(handle),
|
||||
})
|
||||
}
|
||||
/// Write a key/value pair to the database. It is not possible to
|
||||
///
|
||||
/// write with empty keys.
|
||||
fn write(e: &Environment, h: &DbHandle, k: &Vec<u8>, v: &Vec<u8>) -> Result<(), MdbError> {
|
||||
info!("excecuting lmdb write");
|
||||
// don't try and write empty keys
|
||||
if k.is_empty() {
|
||||
error!("can't write empty key");
|
||||
return;
|
||||
return Err(MdbError::NotFound);
|
||||
}
|
||||
let txn = e.new_transaction().unwrap();
|
||||
let new_txn = e.new_transaction()?;
|
||||
let txn = new_txn;
|
||||
{
|
||||
// get a database bound to this transaction
|
||||
let db = txn.bind(h);
|
||||
let pair = [(k, v)];
|
||||
let db: Database = txn.bind(h);
|
||||
let pair: Vec<(&Vec<u8>, &Vec<u8>)> = vec![(k, v)];
|
||||
for &(key, value) in pair.iter() {
|
||||
db.set(&key, &value).unwrap();
|
||||
db.set(key, value)
|
||||
.unwrap_or_else(|_| error!("failed to set key: {:?}", k));
|
||||
}
|
||||
}
|
||||
if txn.commit().is_err() { error!("failed to commit!") }
|
||||
txn.commit()
|
||||
}
|
||||
pub async fn async_write(e: &Environment, h: &DbHandle, k: &str, v: &str) {
|
||||
info!("excecuting lmdb async write");
|
||||
tokio::time::sleep(std::time::Duration::from_micros(1)).await;
|
||||
self::Interface::write(e, h, k, v)
|
||||
}
|
||||
/// Read a value from LMDB by passing the key as a static
|
||||
/// Read key from the database. If it doesn't exist then
|
||||
///
|
||||
/// string. If the value does not exist an empty string is
|
||||
/// an empty vector will be returned. Treat all empty vectors
|
||||
///
|
||||
/// returned. NEVEKO does not currently support duplicate keys.
|
||||
pub fn read(e: &Environment, h: &DbHandle, k: &str) -> String {
|
||||
/// from database operations as failures.
|
||||
pub fn read(e: &Environment, h: &DbHandle, k: &Vec<u8>) -> Result<Vec<u8>, MdbError> {
|
||||
info!("excecuting lmdb read");
|
||||
// don't try and read empty keys
|
||||
if k.is_empty() {
|
||||
error!("can't read empty key");
|
||||
return utils::empty_string();
|
||||
return Err(MdbError::NotFound);
|
||||
}
|
||||
let get_reader = e.get_reader();
|
||||
let reader: ReadonlyTransaction = get_reader?;
|
||||
let db: Database = reader.bind(h);
|
||||
let mut result: Vec<u8> = Vec::new();
|
||||
for num_writes in 0..usize::MAX {
|
||||
let mut new_key: Vec<u8> = k.to_vec();
|
||||
let mut key_count: Vec<u8> = (num_writes).to_be_bytes().to_vec();
|
||||
new_key.append(&mut key_count);
|
||||
let mut r = db.get::<Vec<u8>>(&new_key).unwrap_or_default();
|
||||
if r.is_empty() {
|
||||
break;
|
||||
}
|
||||
result.append(&mut r);
|
||||
}
|
||||
let reader = e.get_reader().unwrap();
|
||||
let db = reader.bind(h);
|
||||
let value = db.get::<&str>(&k).unwrap_or("");
|
||||
let r = String::from(value);
|
||||
{
|
||||
if r == utils::empty_string() {
|
||||
debug!("Failed to read from db.")
|
||||
if result.is_empty() {
|
||||
error!("failed to read key {:?} from db", k);
|
||||
}
|
||||
}
|
||||
r
|
||||
Ok(result)
|
||||
}
|
||||
pub async fn async_read(e: &Environment, h: &DbHandle, k: &str) -> String {
|
||||
info!("excecuting lmdb async read");
|
||||
tokio::time::sleep(std::time::Duration::from_micros(1)).await;
|
||||
self::Interface::read(e, h, k)
|
||||
}
|
||||
/// Delete a value from LMDB by passing the key as a
|
||||
///
|
||||
/// static string. If the value does not exist then an
|
||||
///
|
||||
/// error will be logged.
|
||||
pub fn delete(e: &Environment, h: &DbHandle, k: &str) {
|
||||
/// Deletes a key/value pair from the database
|
||||
pub fn delete(e: &Environment, h: &DbHandle, k: &[u8]) -> Result<(), MdbError> {
|
||||
info!("excecuting lmdb delete");
|
||||
// don't try and delete empty keys
|
||||
if k.is_empty() {
|
||||
error!("can't delete empty key");
|
||||
return;
|
||||
return Err(MdbError::NotFound);
|
||||
}
|
||||
let txn = e.new_transaction().unwrap();
|
||||
let new_txn = e.new_transaction();
|
||||
let txn = new_txn?;
|
||||
let get_reader = e.get_reader();
|
||||
let reader: ReadonlyTransaction = get_reader?;
|
||||
let db_reader: Database = reader.bind(h);
|
||||
{
|
||||
// get a database bound to this transaction
|
||||
let db = txn.bind(h);
|
||||
db.del(&k).unwrap_or_else(|_| error!("failed to delete"));
|
||||
|
||||
for num_writes in 0..usize::MAX {
|
||||
let mut new_key: Vec<u8> = k.to_vec();
|
||||
let mut key_count: Vec<u8> = num_writes.to_be_bytes().to_vec();
|
||||
new_key.append(&mut key_count);
|
||||
let r = db_reader.get::<Vec<u8>>(&new_key).unwrap_or_default();
|
||||
if r.is_empty() {
|
||||
break;
|
||||
}
|
||||
if txn.commit().is_err() { error!("failed to commit!") }
|
||||
db.del(&new_key)
|
||||
.unwrap_or_else(|_| error!("failed to delete"));
|
||||
}
|
||||
}
|
||||
txn.commit()
|
||||
}
|
||||
}
|
||||
|
||||
/// Write chunks to the database. This function uses one percent
|
||||
///
|
||||
/// of the map size . Setting the map_size to a low value
|
||||
///
|
||||
/// will cause degraded performance.
|
||||
pub fn write_chunks(e: &Environment, h: &DbHandle, k: &[u8], v: &[u8]) -> Result<(), MdbError> {
|
||||
let s = System::new_all();
|
||||
let chunk_size = (s.available_memory() as f32 * CHUNK_SIZE_MEMORY_RATIO) as usize;
|
||||
let mut writes: usize = 1;
|
||||
let mut index: usize = 0;
|
||||
let length = v.len();
|
||||
loop {
|
||||
let mut old_key: Vec<u8> = k.to_vec();
|
||||
let mut append: Vec<u8> = (writes - 1).to_be_bytes().to_vec();
|
||||
old_key.append(&mut append);
|
||||
if length > chunk_size && (length - index > chunk_size) {
|
||||
// write chunks until the last value which is smaller than chunk_size
|
||||
let _ = DatabaseEnvironment::write(
|
||||
e,
|
||||
h,
|
||||
&old_key,
|
||||
&v[index..(chunk_size * writes)].to_vec(),
|
||||
);
|
||||
index += chunk_size;
|
||||
writes += 1;
|
||||
} else {
|
||||
DatabaseEnvironment::write(e, h, &old_key, &v[index..length].to_vec())?;
|
||||
return Ok(());
|
||||
}
|
||||
pub async fn async_delete(e: &Environment, h: &DbHandle, k: &str) {
|
||||
info!("excecuting lmdb async delete");
|
||||
tokio::time::sleep(std::time::Duration::from_micros(1)).await;
|
||||
self::Interface::delete(e, h, k)
|
||||
}
|
||||
}
|
||||
|
||||
// Tests
|
||||
//-------------------------------------------------------------------------------
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn async_write_and_read_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();
|
||||
tokio::spawn(async move {
|
||||
let s = Interface::async_open().await;
|
||||
let k = "async-test-key";
|
||||
let v = "async-test-value";
|
||||
Interface::async_write(&s.env, &s.handle, k, v).await;
|
||||
let expected = String::from(v);
|
||||
let actual = Interface::async_read(&s.env, &s.handle, k).await;
|
||||
assert_eq!(expected, actual);
|
||||
Interface::async_delete(&s.env, &s.handle, &k).await;
|
||||
});
|
||||
}
|
||||
use rand::RngCore;
|
||||
|
||||
#[test]
|
||||
fn async_write_and_delete_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();
|
||||
tokio::spawn(async move {
|
||||
let s = Interface::open();
|
||||
let k = "write_and_delete_test_test-key";
|
||||
let v = "write_and_delete_test_test-value";
|
||||
Interface::async_write(&s.env, &s.handle, k, v).await;
|
||||
let expected = utils::empty_string();
|
||||
Interface::async_delete(&s.env, &s.handle, &k).await;
|
||||
let actual = Interface::async_read(&s.env, &s.handle, k).await;
|
||||
assert_eq!(expected, actual);
|
||||
});
|
||||
fn environment_test() -> Result<(), MdbError> {
|
||||
let db = DatabaseEnvironment::open("10-mb-test")?;
|
||||
const DATA_SIZE_10MB: usize = 10000000;
|
||||
let mut data = vec![0u8; DATA_SIZE_10MB];
|
||||
rand::thread_rng().fill_bytes(&mut data);
|
||||
let k = "test-key".as_bytes();
|
||||
let expected = &data.to_vec();
|
||||
write_chunks(&db.env, &db.handle?, &Vec::from(k), &Vec::from(data))?;
|
||||
let db = DatabaseEnvironment::open("10-mb-test")?;
|
||||
let actual = DatabaseEnvironment::read(&db.env, &db.handle?, &Vec::from(k));
|
||||
assert_eq!(expected.to_vec(), actual?);
|
||||
let db = DatabaseEnvironment::open("10-mb-test")?;
|
||||
let _ = DatabaseEnvironment::delete(&db.env, &db.handle?, &Vec::from(k));
|
||||
let db = DatabaseEnvironment::open("100-mb-test")?;
|
||||
const DATA_SIZE_100MB: usize = 100000000;
|
||||
let mut data = vec![0u8; DATA_SIZE_100MB];
|
||||
rand::thread_rng().fill_bytes(&mut data);
|
||||
let k = "test-key".as_bytes();
|
||||
let expected = &data.to_vec();
|
||||
write_chunks(&db.env, &db.handle?, &Vec::from(k), &Vec::from(data))?;
|
||||
let db = DatabaseEnvironment::open("100-mb-test")?;
|
||||
let actual = DatabaseEnvironment::read(&db.env, &db.handle?, &Vec::from(k));
|
||||
assert_eq!(expected.to_vec(), actual?);
|
||||
let db = DatabaseEnvironment::open("100-mb-test")?;
|
||||
let _ = DatabaseEnvironment::delete(&db.env, &db.handle?, &Vec::from(k));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,13 +26,13 @@ pub fn create(d: Json<Dispute>) -> Dispute {
|
|||
tx_set: String::from(&d.tx_set),
|
||||
};
|
||||
debug!("insert dispute: {:?}", &d);
|
||||
let s = db::Interface::open();
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
let k = &d.did;
|
||||
db::Interface::write(&s.env, &s.handle, k, &Dispute::to_db(&new_dispute));
|
||||
db::DatabaseEnvironment::write(&s.env, &s.handle, k, &Dispute::to_db(&new_dispute));
|
||||
// in order to retrieve all orders, write keys to with dl
|
||||
let list_key = crate::DISPUTE_LIST_DB_KEY;
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
||||
if r == utils::empty_string() {
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, &String::from(list_key));
|
||||
if r.is_empty() {
|
||||
debug!("creating dispute index");
|
||||
}
|
||||
let dispute_list = [String::from(&r), String::from(&f_did)].join(",");
|
||||
|
@ -40,7 +40,7 @@ pub fn create(d: Json<Dispute>) -> Dispute {
|
|||
"writing dispute index {} for id: {}",
|
||||
dispute_list, list_key
|
||||
);
|
||||
db::Interface::write(&s.env, &s.handle, &String::from(list_key), &dispute_list);
|
||||
db::DatabaseEnvironment::write(&s.env, &s.handle, &String::from(list_key), &dispute_list);
|
||||
// restart the dispute aut-settle thread
|
||||
let cleared = is_dispute_clear(r);
|
||||
if !cleared {
|
||||
|
@ -52,9 +52,9 @@ pub fn create(d: Json<Dispute>) -> Dispute {
|
|||
|
||||
/// Dispute lookup
|
||||
pub fn find(did: &String) -> Dispute {
|
||||
let s = db::Interface::open();
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(did));
|
||||
if r == utils::empty_string() {
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, &String::from(did));
|
||||
if r.is_empty() {
|
||||
error!("dispute not found");
|
||||
return Default::default();
|
||||
}
|
||||
|
@ -63,10 +63,10 @@ pub fn find(did: &String) -> Dispute {
|
|||
|
||||
/// Lookup all disputes
|
||||
pub fn find_all() -> Vec<Dispute> {
|
||||
let d_s = db::Interface::open();
|
||||
let d_s = db::DatabaseEnvironment::open();
|
||||
let d_list_key = crate::DISPUTE_LIST_DB_KEY;
|
||||
let d_r = db::Interface::read(&d_s.env, &d_s.handle, &String::from(d_list_key));
|
||||
if d_r == utils::empty_string() {
|
||||
let d_r = db::DatabaseEnvironment::read(&d_s.env, &d_s.handle, &String::from(d_list_key));
|
||||
if d_r.is_empty() {
|
||||
error!("dispute index not found");
|
||||
}
|
||||
let d_v_did = d_r.split(",");
|
||||
|
@ -74,7 +74,7 @@ pub fn find_all() -> Vec<Dispute> {
|
|||
let mut disputes: Vec<Dispute> = Vec::new();
|
||||
for o in d_v {
|
||||
let dispute: Dispute = find(&o);
|
||||
if dispute.did != utils::empty_string() {
|
||||
if !dispute.did.is_empty() {
|
||||
disputes.push(dispute);
|
||||
}
|
||||
}
|
||||
|
@ -83,13 +83,13 @@ pub fn find_all() -> Vec<Dispute> {
|
|||
|
||||
/// Dispute deletion
|
||||
pub fn delete(did: &String) {
|
||||
let s = db::Interface::open();
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(did));
|
||||
if r == utils::empty_string() {
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, &String::from(did));
|
||||
if r.is_empty() {
|
||||
error!("dispute not found");
|
||||
return Default::default();
|
||||
}
|
||||
db::Interface::delete(&s.env, &s.handle, &String::from(did))
|
||||
db::DatabaseEnvironment::delete(&s.env, &s.handle, &String::from(did))
|
||||
}
|
||||
|
||||
/// Triggered on DISPUTE_LAST_CHECK_DB_KEY.
|
||||
|
@ -105,10 +105,10 @@ pub async fn settle_dispute() {
|
|||
loop {
|
||||
debug!("running dispute auto-settle thread");
|
||||
tick.recv().unwrap();
|
||||
let s = db::Interface::open();
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
let list_key = crate::DISPUTE_LIST_DB_KEY;
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
||||
if r == utils::empty_string() {
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, &String::from(list_key));
|
||||
if r.is_empty() {
|
||||
info!("dispute index not found");
|
||||
}
|
||||
let v_mid = r.split(",");
|
||||
|
@ -118,17 +118,17 @@ pub async fn settle_dispute() {
|
|||
if cleared {
|
||||
// index was created but cleared
|
||||
info!("terminating dispute auto-settle thread");
|
||||
db::Interface::delete(&s.env, &s.handle, list_key);
|
||||
db::DatabaseEnvironment::delete(&s.env, &s.handle, list_key);
|
||||
return;
|
||||
}
|
||||
for d in d_vec {
|
||||
let dispute: Dispute = find(&d);
|
||||
if dispute.did != utils::empty_string() {
|
||||
if !dispute.did.is_empty() {
|
||||
let now = chrono::offset::Utc::now().timestamp();
|
||||
let settle_date = dispute.created + crate::DISPUTE_AUTO_SETTLE as i64;
|
||||
if settle_date > now {
|
||||
let wallet_name = dispute.orid;
|
||||
let wallet_password = utils::empty_string();
|
||||
let wallet_password = String::new();
|
||||
monero::open_wallet(&wallet_name, &wallet_password).await;
|
||||
let signed = monero::sign_multisig(dispute.tx_set).await;
|
||||
let submit = monero::submit_multisig(signed.result.tx_data_hex).await;
|
||||
|
@ -152,8 +152,8 @@ fn is_dispute_clear(r: String) -> bool {
|
|||
let limit = v.len() <= 1;
|
||||
if !limit {
|
||||
v.len() >= 2
|
||||
&& v[v.len() - 1] == utils::empty_string()
|
||||
&& v[0] == utils::empty_string()
|
||||
&& v[v.len() - 1].is_empty()
|
||||
&& v[0].is_empty()
|
||||
} else {
|
||||
limit
|
||||
}
|
||||
|
@ -162,10 +162,10 @@ fn is_dispute_clear(r: String) -> bool {
|
|||
/// clear dispute from index
|
||||
fn remove_from_auto_settle(did: String) {
|
||||
info!("removing id {} from disputes", &did);
|
||||
let s = db::Interface::open();
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
let list_key = crate::DISPUTE_LIST_DB_KEY;
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
||||
if r == utils::empty_string() {
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, &String::from(list_key));
|
||||
if r.is_empty() {
|
||||
debug!("dispute list index is empty");
|
||||
}
|
||||
let pre_v_fts = r.split(",");
|
||||
|
@ -174,7 +174,7 @@ fn remove_from_auto_settle(did: String) {
|
|||
if s != &did {
|
||||
String::from(s)
|
||||
} else {
|
||||
utils::empty_string()
|
||||
String::new()
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
@ -183,7 +183,7 @@ fn remove_from_auto_settle(did: String) {
|
|||
"writing dipsute index {} for id: {}",
|
||||
dispute_list, list_key
|
||||
);
|
||||
db::Interface::write(&s.env, &s.handle, &String::from(list_key), &dispute_list);
|
||||
db::DatabaseEnvironment::write(&s.env, &s.handle, &String::from(list_key), &dispute_list);
|
||||
}
|
||||
|
||||
/// Executes POST /market/dispute/create
|
||||
|
@ -229,9 +229,9 @@ async fn transmit_dispute_request(
|
|||
/// can be executed from the gui.
|
||||
pub async fn trigger_dispute_request(contact: &String, dispute: &Dispute) -> Dispute {
|
||||
info!("executing trigger_dispute_request");
|
||||
let s = db::Interface::async_open().await;
|
||||
let s = db::DatabaseEnvironment::async_open().await;
|
||||
let k = format!("{}-{}", crate::FTS_JWP_DB_KEY, &contact);
|
||||
let jwp = db::Interface::async_read(&s.env, &s.handle, &k).await;
|
||||
let jwp = db::DatabaseEnvironment::async_read(&s.env, &s.handle, &k).await;
|
||||
let dispute = transmit_dispute_request(contact, &jwp, dispute).await;
|
||||
// handle a failure to create dispute
|
||||
if dispute.is_err() {
|
||||
|
|
12
neveko-core/src/error.rs
Normal file
12
neveko-core/src/error.rs
Normal file
|
@ -0,0 +1,12 @@
|
|||
use kn0sys_lmdb_rs::MdbError;
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
#[error("neveko error. See logs for more info.")]
|
||||
pub enum NevekoError {
|
||||
///J4I2PRS(J4RsError),
|
||||
Database(MdbError),
|
||||
MoneroRpc,
|
||||
MoneroDaemon,
|
||||
Unknown,
|
||||
}
|
|
@ -65,7 +65,7 @@ async fn find_tunnels() {
|
|||
"/home/{}/.i2p-zero/config/tunnels.json",
|
||||
env::var("USER").unwrap_or(String::from("user"))
|
||||
);
|
||||
let contents = fs::read_to_string(file_path).unwrap_or(utils::empty_string());
|
||||
let contents = fs::read_to_string(file_path).unwrap_or(String::new());
|
||||
debug!("i2p tunnels: {}", contents);
|
||||
let has_app_tunnel = contents.contains(&format!("{}", app_port));
|
||||
let proxy_port = get_i2p_proxy_port();
|
||||
|
@ -209,11 +209,11 @@ pub fn get_destination(port: Option<u16>) -> String {
|
|||
);
|
||||
let args = args::Args::parse();
|
||||
let is_advanced_mode =
|
||||
std::env::var(crate::NEVEKO_I2P_ADVANCED_MODE).unwrap_or(utils::empty_string());
|
||||
std::env::var(crate::NEVEKO_I2P_ADVANCED_MODE).unwrap_or(String::new());
|
||||
if args.i2p_advanced || is_advanced_mode == *"1" {
|
||||
let advanced_tunnel =
|
||||
std::env::var(crate::NEVEKO_I2P_TUNNELS_JSON).unwrap_or(utils::empty_string());
|
||||
let manual_tunnel = if advanced_tunnel == utils::empty_string() {
|
||||
std::env::var(crate::NEVEKO_I2P_TUNNELS_JSON).unwrap_or(String::new());
|
||||
let manual_tunnel = if advanced_tunnel.is_empty() {
|
||||
args.i2p_tunnels_json
|
||||
} else {
|
||||
advanced_tunnel
|
||||
|
@ -223,21 +223,21 @@ pub fn get_destination(port: Option<u16>) -> String {
|
|||
// Don't panic if i2p-zero isn't installed
|
||||
let contents = match fs::read_to_string(file_path) {
|
||||
Ok(file) => file,
|
||||
_ => utils::empty_string(),
|
||||
_ => String::new(),
|
||||
};
|
||||
if contents != utils::empty_string() {
|
||||
if !contents.is_empty() {
|
||||
let input = contents.to_string();
|
||||
let j: Tunnels = serde_json::from_str(&input).unwrap_or(Default::default());
|
||||
let mut destination: String = utils::empty_string();
|
||||
let mut destination: String = String::new();
|
||||
let tunnels: Vec<Tunnel> = j.tunnels;
|
||||
for tunnel in tunnels {
|
||||
if tunnel.port == format!("{}", port.unwrap_or(utils::get_app_port())) {
|
||||
destination = tunnel.dest.unwrap_or(utils::empty_string());
|
||||
destination = tunnel.dest.unwrap_or(String::new());
|
||||
}
|
||||
}
|
||||
return destination;
|
||||
}
|
||||
utils::empty_string()
|
||||
String::new()
|
||||
}
|
||||
|
||||
/// Ping the i2p-zero http proxy `tunnel-control http.state <port>`
|
||||
|
|
|
@ -4,6 +4,7 @@ pub mod contact;
|
|||
pub mod neveko25519;
|
||||
pub mod dispute;
|
||||
pub mod db;
|
||||
pub mod error;
|
||||
pub mod i2p;
|
||||
pub mod message;
|
||||
pub mod models;
|
||||
|
@ -60,15 +61,6 @@ pub const MONERO_WALLET_RPC_HOST: &str = "MONERO_WALLET_RPC_HOST";
|
|||
pub const GUI_REMOTE_NODE: &str = "GUI_REMOTE_NODE";
|
||||
pub const GUI_SET_REMOTE_NODE: &str = "1";
|
||||
|
||||
/// The latest monero release download
|
||||
pub const MONERO_RELEASE_VERSION: &str = "monero-linux-x64-v0.18.3.2.tar.bz2";
|
||||
pub const MONERO_RELEASE_HASH: &str =
|
||||
"9dafd70230a7b3a73101b624f3b5f439cc5b84a19b12c17c24e6aab94b678cbb";
|
||||
/// The latest i2p-zero release version
|
||||
pub const I2P_ZERO_RELEASE_VERSION: &str = "v1.21";
|
||||
pub const I2P_ZERO_RELEASH_HASH: &str =
|
||||
"14f34052ad6abb0c24b048816b0ea86b696ae350dd139dd1e90a67ca88e1d07a";
|
||||
|
||||
pub const LMDB_MAPSIZE: u64 = 1024 * 1024 * 1024;
|
||||
pub const I2P_CONNECTIVITY_CHECK_INTERVAL: u32 = 600000;
|
||||
pub const FTS_RETRY_INTERVAL: u32 = 60000;
|
||||
|
|
|
@ -36,22 +36,13 @@ pub enum MessageType {
|
|||
Multisig,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct MultisigMessageData {
|
||||
info: String,
|
||||
sub_type: String,
|
||||
orid: String,
|
||||
}
|
||||
|
||||
impl Default for MultisigMessageData {
|
||||
fn default() -> Self {
|
||||
MultisigMessageData {
|
||||
info: utils::empty_string(),
|
||||
sub_type: utils::empty_string(),
|
||||
orid: utils::empty_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new message
|
||||
pub async fn create(m: Json<Message>, jwp: String, m_type: MessageType) -> Message {
|
||||
let rnd = utils::generate_rnd();
|
||||
|
@ -76,18 +67,18 @@ 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::Interface::open();
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
let k = &new_message.mid;
|
||||
db::Interface::write(&s.env, &s.handle, k, &Message::to_db(&new_message));
|
||||
db::DatabaseEnvironment::write(&s.env, &s.handle, k, &Message::to_db(&new_message));
|
||||
// in order to retrieve all message, write keys to with ml
|
||||
let list_key = crate::MESSAGE_LIST_DB_KEY;
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
||||
if r == utils::empty_string() {
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, &String::from(list_key));
|
||||
if r.is_empty() {
|
||||
debug!("creating message index");
|
||||
}
|
||||
let msg_list = [r, String::from(&f_mid)].join(",");
|
||||
debug!("writing message index {} for id: {}", msg_list, list_key);
|
||||
db::Interface::write(&s.env, &s.handle, &String::from(list_key), &msg_list);
|
||||
db::DatabaseEnvironment::write(&s.env, &s.handle, &String::from(list_key), &msg_list);
|
||||
info!("attempting to send message");
|
||||
let send = send_message(&new_message, &jwp, m_type).await;
|
||||
send.unwrap();
|
||||
|
@ -116,25 +107,25 @@ pub async fn rx(m: Json<Message>) {
|
|||
to: String::from(&m.to),
|
||||
};
|
||||
debug!("insert message: {:?}", &new_message);
|
||||
let s = db::Interface::open();
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
let k = &new_message.mid;
|
||||
db::Interface::write(&s.env, &s.handle, k, &Message::to_db(&new_message));
|
||||
db::DatabaseEnvironment::write(&s.env, &s.handle, k, &Message::to_db(&new_message));
|
||||
// in order to retrieve all message, write keys to with rx
|
||||
let list_key = crate::RX_MESSAGE_DB_KEY;
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
||||
if r == utils::empty_string() {
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, &String::from(list_key));
|
||||
if r.is_empty() {
|
||||
debug!("creating message index");
|
||||
}
|
||||
let msg_list = [r, String::from(&f_mid)].join(",");
|
||||
debug!("writing message index {} for {}", msg_list, list_key);
|
||||
db::Interface::write(&s.env, &s.handle, &String::from(list_key), &msg_list);
|
||||
db::DatabaseEnvironment::write(&s.env, &s.handle, &String::from(list_key), &msg_list);
|
||||
}
|
||||
|
||||
/// Parse the multisig message type and info
|
||||
async fn parse_multisig_message(mid: String) -> MultisigMessageData {
|
||||
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(utils::empty_string());
|
||||
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 {
|
||||
|
@ -176,9 +167,9 @@ async fn parse_multisig_message(mid: String) -> MultisigMessageData {
|
|||
/// ```rust
|
||||
/// // lookup prepare info for vendor
|
||||
/// use neveko_core::db;
|
||||
/// let s = db::Interface::open();
|
||||
/// let s = db::DatabaseEnvironment::open();
|
||||
/// let key = "prepare-o123-test.b32.i2p";
|
||||
/// let info_str = db::Interface::read(&s.env, &s.handle, &key);
|
||||
/// let info_str = db::DatabaseEnvironment::read(&s.env, &s.handle, &key);
|
||||
/// ```
|
||||
pub async fn rx_multisig(m: Json<Message>) {
|
||||
// make sure the message isn't something strange
|
||||
|
@ -200,13 +191,13 @@ pub async fn rx_multisig(m: Json<Message>) {
|
|||
created: chrono::offset::Utc::now().timestamp(),
|
||||
to: String::from(&m.to),
|
||||
};
|
||||
let s = db::Interface::async_open().await;
|
||||
let s = db::DatabaseEnvironment::async_open().await;
|
||||
let k = &new_message.mid;
|
||||
db::Interface::async_write(&s.env, &s.handle, k, &Message::to_db(&new_message)).await;
|
||||
db::DatabaseEnvironment::async_write(&s.env, &s.handle, k, &Message::to_db(&new_message)).await;
|
||||
// in order to retrieve all msig messages, write keys to with msigl
|
||||
let list_key = crate::MSIG_MESSAGE_LIST_DB_KEY;
|
||||
let r = db::Interface::async_read(&s.env, &s.handle, &String::from(list_key)).await;
|
||||
if r == utils::empty_string() {
|
||||
let r = db::DatabaseEnvironment::async_read(&s.env, &s.handle, &String::from(list_key)).await;
|
||||
if r.is_empty() {
|
||||
debug!("creating msig message index");
|
||||
}
|
||||
let msg_list = [r, String::from(&f_mid)].join(",");
|
||||
|
@ -214,7 +205,7 @@ pub async fn rx_multisig(m: Json<Message>) {
|
|||
"writing msig message index {} for id: {}",
|
||||
msg_list, list_key
|
||||
);
|
||||
db::Interface::async_write(&s.env, &s.handle, &String::from(list_key), &msg_list).await;
|
||||
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;
|
||||
debug!(
|
||||
"writing multisig message type {} for order {}",
|
||||
|
@ -222,16 +213,16 @@ pub async fn rx_multisig(m: Json<Message>) {
|
|||
);
|
||||
// lookup msig message data by {type}-{order id}-{contact .b32.i2p address}
|
||||
// store info as {a_info}:{a_info (optional)}
|
||||
let s_msig = db::Interface::async_open().await;
|
||||
let s_msig = db::DatabaseEnvironment::async_open().await;
|
||||
let msig_key = format!("{}-{}-{}", &data.sub_type, &data.orid, &m.from);
|
||||
db::Interface::async_write(&s_msig.env, &s_msig.handle, &msig_key, &data.info).await;
|
||||
db::DatabaseEnvironment::async_write(&s_msig.env, &s_msig.handle, &msig_key, &data.info).await;
|
||||
}
|
||||
|
||||
/// Message lookup
|
||||
pub fn find(mid: &String) -> Message {
|
||||
let s = db::Interface::open();
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(mid));
|
||||
if r == utils::empty_string() {
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, &String::from(mid));
|
||||
if r.is_empty() {
|
||||
error!("message not found");
|
||||
return Default::default();
|
||||
}
|
||||
|
@ -240,10 +231,10 @@ pub fn find(mid: &String) -> Message {
|
|||
|
||||
/// Message lookup
|
||||
pub fn find_all() -> Vec<Message> {
|
||||
let i_s = db::Interface::open();
|
||||
let i_s = db::DatabaseEnvironment::open();
|
||||
let i_list_key = crate::MESSAGE_LIST_DB_KEY;
|
||||
let i_r = db::Interface::read(&i_s.env, &i_s.handle, &String::from(i_list_key));
|
||||
if i_r == utils::empty_string() {
|
||||
let i_r = db::DatabaseEnvironment::read(&i_s.env, &i_s.handle, &String::from(i_list_key));
|
||||
if i_r.is_empty() {
|
||||
error!("message index not found");
|
||||
}
|
||||
let i_v_mid = i_r.split(",");
|
||||
|
@ -251,21 +242,21 @@ pub fn find_all() -> Vec<Message> {
|
|||
let mut messages: Vec<Message> = Vec::new();
|
||||
for m in i_v {
|
||||
let message: Message = find(&m);
|
||||
if message.mid != utils::empty_string() {
|
||||
if !message.mid.is_empty() {
|
||||
messages.push(message);
|
||||
}
|
||||
}
|
||||
let o_list_key = crate::RX_MESSAGE_DB_KEY;
|
||||
let o_s = db::Interface::open();
|
||||
let o_r = db::Interface::read(&o_s.env, &o_s.handle, &String::from(o_list_key));
|
||||
if o_r == utils::empty_string() {
|
||||
let o_s = db::DatabaseEnvironment::open();
|
||||
let o_r = db::DatabaseEnvironment::read(&o_s.env, &o_s.handle, &String::from(o_list_key));
|
||||
if o_r.is_empty() {
|
||||
error!("message index not found");
|
||||
}
|
||||
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);
|
||||
if message.mid != utils::empty_string() {
|
||||
if !message.mid.is_empty() {
|
||||
messages.push(message);
|
||||
}
|
||||
}
|
||||
|
@ -326,8 +317,8 @@ pub async fn decipher_body(mid: String) -> reqres::DecipheredMessageBody {
|
|||
|
||||
/// Message deletion
|
||||
pub fn delete(mid: &String) {
|
||||
let s = db::Interface::open();
|
||||
db::Interface::delete(&s.env, &s.handle, &String::from(mid));
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
db::DatabaseEnvironment::delete(&s.env, &s.handle, &String::from(mid));
|
||||
}
|
||||
|
||||
/// ping the contact health check over i2p
|
||||
|
@ -365,11 +356,11 @@ 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) {
|
||||
info!("sending {} to fts", &mid);
|
||||
let s = db::Interface::open();
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
// in order to retrieve FTS (failed-to-send), write keys to db with fts
|
||||
let list_key = crate::FTS_DB_KEY;
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
||||
if r == utils::empty_string() {
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, &String::from(list_key));
|
||||
if r.is_empty() {
|
||||
debug!("creating fts message index");
|
||||
}
|
||||
let mut msg_list = [String::from(&r), String::from(&mid)].join(",");
|
||||
|
@ -381,9 +372,9 @@ async fn send_to_retry(mid: String) {
|
|||
"writing fts message index {} for id: {}",
|
||||
msg_list, list_key
|
||||
);
|
||||
db::Interface::write(&s.env, &s.handle, &String::from(list_key), &msg_list);
|
||||
db::DatabaseEnvironment::write(&s.env, &s.handle, &String::from(list_key), &msg_list);
|
||||
// restart fts if not empty
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, &String::from(list_key));
|
||||
let v_mid = r.split(",");
|
||||
let v: Vec<String> = v_mid.map(String::from).collect();
|
||||
debug!("fts contents: {:#?}", v);
|
||||
|
@ -397,11 +388,11 @@ async fn send_to_retry(mid: String) {
|
|||
/// clear fts message from index
|
||||
fn remove_from_fts(mid: String) {
|
||||
info!("removing id {} from fts", &mid);
|
||||
let s = db::Interface::open();
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
// in order to retrieve FTS (failed-to-send), write keys to with fts
|
||||
let list_key = crate::FTS_DB_KEY;
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
||||
if r == utils::empty_string() {
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, &String::from(list_key));
|
||||
if r.is_empty() {
|
||||
debug!("fts is empty");
|
||||
}
|
||||
let pre_v_fts = r.split(",");
|
||||
|
@ -410,7 +401,7 @@ fn remove_from_fts(mid: String) {
|
|||
if s != &mid {
|
||||
String::from(s)
|
||||
} else {
|
||||
utils::empty_string()
|
||||
String::new()
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
@ -419,7 +410,7 @@ fn remove_from_fts(mid: String) {
|
|||
"writing fts message index {} for id: {}",
|
||||
msg_list, list_key
|
||||
);
|
||||
db::Interface::write(&s.env, &s.handle, &String::from(list_key), &msg_list);
|
||||
db::DatabaseEnvironment::write(&s.env, &s.handle, &String::from(list_key), &msg_list);
|
||||
}
|
||||
|
||||
/// Triggered on app startup, retries to send fts every minute
|
||||
|
@ -432,10 +423,10 @@ pub async fn retry_fts() {
|
|||
loop {
|
||||
debug!("running retry failed-to-send thread");
|
||||
tick.recv().unwrap();
|
||||
let s = db::Interface::open();
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
let list_key = crate::FTS_DB_KEY;
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
||||
if r == utils::empty_string() {
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, &String::from(list_key));
|
||||
if r.is_empty() {
|
||||
info!("fts message index not found");
|
||||
break; // terminate fts if no message to send
|
||||
}
|
||||
|
@ -446,17 +437,17 @@ pub async fn retry_fts() {
|
|||
if cleared {
|
||||
// index was created but cleared
|
||||
info!("terminating retry fts thread");
|
||||
db::Interface::delete(&s.env, &s.handle, list_key);
|
||||
db::DatabaseEnvironment::delete(&s.env, &s.handle, list_key);
|
||||
break;
|
||||
}
|
||||
for m in v {
|
||||
let message: Message = find(&m);
|
||||
if message.mid != utils::empty_string() {
|
||||
let s = db::Interface::open();
|
||||
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::Interface::read(&s.env, &s.handle, &k);
|
||||
if jwp != utils::empty_string() {
|
||||
let jwp = db::DatabaseEnvironment::read(&s.env, &s.handle, &k);
|
||||
if !jwp.is_empty() {
|
||||
let m_type = if message.mid.contains("msig") {
|
||||
MessageType::Multisig
|
||||
} else {
|
||||
|
@ -487,8 +478,8 @@ fn is_fts_clear(r: String) -> bool {
|
|||
let limit = v.len() <= 1;
|
||||
if !limit {
|
||||
v.len() >= 2
|
||||
&& v[v.len() - 1] == utils::empty_string()
|
||||
&& v[0] == utils::empty_string()
|
||||
&& v[v.len() - 1].is_empty()
|
||||
&& v[0].is_empty()
|
||||
} else {
|
||||
limit
|
||||
}
|
||||
|
@ -498,13 +489,13 @@ fn is_fts_clear(r: String) -> bool {
|
|||
///
|
||||
/// `prepare_multisig_info` method.
|
||||
pub async fn send_prepare_info(orid: &String, contact: &String) {
|
||||
let s = db::Interface::open();
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
let wallet_name = String::from(orid);
|
||||
let wallet_password = utils::empty_string();
|
||||
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::Interface::read(&s.env, &s.handle, &k);
|
||||
let jwp = db::DatabaseEnvironment::read(&s.env, &s.handle, &k);
|
||||
let body_str = format!(
|
||||
"{}:{}:{}",
|
||||
PREPARE_MSIG, orid, &prepare_info.result.multisig_info
|
||||
|
@ -524,13 +515,13 @@ pub async fn send_prepare_info(orid: &String, contact: &String) {
|
|||
///
|
||||
/// `make_multisig_info` method.
|
||||
pub async fn send_make_info(orid: &String, contact: &String, info: Vec<String>) {
|
||||
let s = db::Interface::open();
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
let wallet_name = String::from(orid);
|
||||
let wallet_password = utils::empty_string();
|
||||
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::Interface::read(&s.env, &s.handle, &k);
|
||||
let jwp = db::DatabaseEnvironment::read(&s.env, &s.handle, &k);
|
||||
let body_str = format!("{}:{}:{}", MAKE_MSIG, orid, &make_info.result.multisig_info);
|
||||
let message: Message = Message {
|
||||
body: body_str,
|
||||
|
@ -552,13 +543,13 @@ pub async fn send_exchange_info(
|
|||
info: Vec<String>,
|
||||
kex_init: bool,
|
||||
) {
|
||||
let s = db::Interface::open();
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
let wallet_name = String::from(orid);
|
||||
let wallet_password = utils::empty_string();
|
||||
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::Interface::read(&s.env, &s.handle, &k);
|
||||
let jwp = db::DatabaseEnvironment::read(&s.env, &s.handle, &k);
|
||||
let mut body_str = format!(
|
||||
"{}:{}:{}",
|
||||
KEX_ONE_MSIG, orid, &exchange_info.result.multisig_info
|
||||
|
@ -584,13 +575,13 @@ pub async fn send_exchange_info(
|
|||
///
|
||||
/// `export_multisig_info` method.
|
||||
pub async fn send_export_info(orid: &String, contact: &String) {
|
||||
let s = db::Interface::open();
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
let wallet_name = String::from(orid);
|
||||
let wallet_password = utils::empty_string();
|
||||
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::Interface::read(&s.env, &s.handle, &k);
|
||||
let jwp = db::DatabaseEnvironment::read(&s.env, &s.handle, &k);
|
||||
let body_str = format!("{}:{}:{}", EXPORT_MSIG, orid, &exchange_info.result.info);
|
||||
let message: Message = Message {
|
||||
body: body_str,
|
||||
|
@ -610,7 +601,7 @@ pub async fn send_export_info(orid: &String, contact: &String) {
|
|||
/// successfully the order needs to be updated to `MultisigComplete`.
|
||||
pub async fn send_import_info(orid: &String, info: &Vec<String>) {
|
||||
let wallet_name = String::from(orid);
|
||||
let wallet_password = utils::empty_string();
|
||||
let wallet_password = String::new();
|
||||
monero::open_wallet(&wallet_name, &wallet_password).await;
|
||||
let pre_import = monero::import_multisig_info(info.to_vec()).await;
|
||||
monero::close_wallet(orid, &wallet_password).await;
|
||||
|
@ -701,8 +692,8 @@ mod tests {
|
|||
|
||||
async fn cleanup(k: &String) {
|
||||
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
|
||||
let s = db::Interface::async_open().await;
|
||||
db::Interface::async_delete(&s.env, &s.handle, k).await;
|
||||
let s = db::DatabaseEnvironment::async_open().await;
|
||||
db::DatabaseEnvironment::async_delete(&s.env, &s.handle, k).await;
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -740,8 +731,8 @@ mod tests {
|
|||
};
|
||||
let k = "test-key";
|
||||
tokio::spawn(async move {
|
||||
let s = db::Interface::async_open().await;
|
||||
db::Interface::async_write(&s.env, &s.handle, k, &Message::to_db(&expected_message))
|
||||
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);
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
//! Custom object relational mapping (ORM) for structs into LMBD
|
||||
|
||||
use crate::utils;
|
||||
use rocket::serde::{
|
||||
json::Json,
|
||||
Deserialize,
|
||||
Serialize,
|
||||
};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[derive(Debug, Default, Serialize, Deserialize)]
|
||||
#[serde(crate = "rocket::serde")]
|
||||
pub struct Authorization {
|
||||
pub aid: String,
|
||||
|
@ -18,47 +17,8 @@ pub struct Authorization {
|
|||
pub xmr_address: String,
|
||||
}
|
||||
|
||||
impl Default for Authorization {
|
||||
fn default() -> Self {
|
||||
Authorization {
|
||||
aid: utils::empty_string(),
|
||||
created: 0,
|
||||
uid: utils::empty_string(),
|
||||
rnd: utils::empty_string(),
|
||||
token: utils::empty_string(),
|
||||
xmr_address: utils::empty_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Authorization {
|
||||
pub fn to_db(a: &Authorization) -> String {
|
||||
format!(
|
||||
"{}:{}:{}:{}:{}",
|
||||
a.created, a.uid, a.rnd, a.token, a.xmr_address
|
||||
)
|
||||
}
|
||||
pub fn from_db(k: String, v: String) -> Authorization {
|
||||
let values = v.split(":");
|
||||
let mut v: Vec<String> = values.map(String::from).collect();
|
||||
let created_str = v.remove(0);
|
||||
let created = match created_str.parse::<i64>() {
|
||||
Ok(n) => n,
|
||||
Err(_e) => 0,
|
||||
};
|
||||
let uid = v.remove(0);
|
||||
let rnd = v.remove(0);
|
||||
let token = v.remove(0);
|
||||
let xmr_address = v.remove(0);
|
||||
Authorization {
|
||||
aid: k,
|
||||
created,
|
||||
uid,
|
||||
rnd,
|
||||
token,
|
||||
xmr_address,
|
||||
}
|
||||
}
|
||||
pub fn update_uid(a: Authorization, uid: String) -> Authorization {
|
||||
Authorization {
|
||||
aid: a.aid,
|
||||
|
@ -86,7 +46,7 @@ impl Authorization {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[derive(Debug, Default, Serialize, Deserialize)]
|
||||
#[serde(crate = "rocket::serde")]
|
||||
pub struct Contact {
|
||||
pub cid: String,
|
||||
|
@ -96,46 +56,7 @@ pub struct Contact {
|
|||
pub nmpk: String,
|
||||
}
|
||||
|
||||
impl Default for Contact {
|
||||
fn default() -> Self {
|
||||
Contact {
|
||||
cid: utils::empty_string(),
|
||||
nmpk: utils::empty_string(),
|
||||
i2p_address: utils::empty_string(),
|
||||
is_vendor: false,
|
||||
xmr_address: utils::empty_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Contact {
|
||||
pub fn to_db(c: &Contact) -> String {
|
||||
format!(
|
||||
"{}!{}!{}!{}",
|
||||
c.nmpk, c.i2p_address, c.is_vendor, c.xmr_address
|
||||
)
|
||||
}
|
||||
pub fn from_db(k: String, v: String) -> Contact {
|
||||
let values = v.split("!");
|
||||
let mut v: Vec<String> = values.map(String::from).collect();
|
||||
let nmpk = v.remove(0);
|
||||
let i2p_address = v.remove(0);
|
||||
let is_vendor = match v.remove(0).parse::<bool>() {
|
||||
Ok(n) => n,
|
||||
Err(_e) => false,
|
||||
};
|
||||
let xmr_address = v.remove(0);
|
||||
Contact {
|
||||
cid: k,
|
||||
nmpk,
|
||||
i2p_address,
|
||||
is_vendor,
|
||||
xmr_address,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[derive(Debug, Default, Serialize, Deserialize)]
|
||||
#[serde(crate = "rocket::serde")]
|
||||
pub struct Message {
|
||||
pub mid: String,
|
||||
|
@ -146,47 +67,7 @@ pub struct Message {
|
|||
pub to: String,
|
||||
}
|
||||
|
||||
impl Default for Message {
|
||||
fn default() -> Self {
|
||||
Message {
|
||||
mid: utils::empty_string(),
|
||||
uid: utils::empty_string(),
|
||||
body: utils::empty_string(),
|
||||
created: 0,
|
||||
from: utils::empty_string(),
|
||||
to: utils::empty_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Message {
|
||||
pub fn to_db(m: &Message) -> String {
|
||||
format!("{}:{}:{}:{}:{}", m.uid, m.body, m.created, m.from, m.to)
|
||||
}
|
||||
pub fn from_db(k: String, v: String) -> Message {
|
||||
let values = v.split(":");
|
||||
let mut v: Vec<String> = values.map(String::from).collect();
|
||||
let uid = v.remove(0);
|
||||
let body = v.remove(0);
|
||||
let created_str = v.remove(0);
|
||||
let created = match created_str.parse::<i64>() {
|
||||
Ok(n) => n,
|
||||
Err(_e) => 0,
|
||||
};
|
||||
let from = v.remove(0);
|
||||
let to = v.remove(0);
|
||||
Message {
|
||||
mid: k,
|
||||
uid,
|
||||
body,
|
||||
created,
|
||||
from,
|
||||
to,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||
#[serde(crate = "rocket::serde")]
|
||||
pub struct User {
|
||||
pub uid: String,
|
||||
|
@ -194,31 +75,7 @@ pub struct User {
|
|||
pub name: String,
|
||||
}
|
||||
|
||||
impl Default for User {
|
||||
fn default() -> Self {
|
||||
User {
|
||||
uid: utils::empty_string(),
|
||||
xmr_address: utils::empty_string(),
|
||||
name: utils::empty_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl User {
|
||||
pub fn to_db(u: &User) -> String {
|
||||
format!("{}:{}", u.name, u.xmr_address)
|
||||
}
|
||||
pub fn from_db(k: String, v: String) -> User {
|
||||
let values = v.split(":");
|
||||
let mut v: Vec<String> = values.map(String::from).collect();
|
||||
let name = v.remove(0);
|
||||
let xmr_address = v.remove(0);
|
||||
User {
|
||||
uid: k,
|
||||
name,
|
||||
xmr_address,
|
||||
}
|
||||
}
|
||||
pub fn update(u: User, name: String) -> User {
|
||||
User {
|
||||
uid: u.uid,
|
||||
|
@ -228,7 +85,7 @@ impl User {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||
#[serde(crate = "rocket::serde")]
|
||||
pub struct Product {
|
||||
pub pid: String,
|
||||
|
@ -240,47 +97,7 @@ pub struct Product {
|
|||
pub qty: u128,
|
||||
}
|
||||
|
||||
impl Default for Product {
|
||||
fn default() -> Self {
|
||||
Product {
|
||||
pid: utils::empty_string(),
|
||||
description: utils::empty_string(),
|
||||
image: Vec::new(),
|
||||
in_stock: false,
|
||||
name: utils::empty_string(),
|
||||
price: 0,
|
||||
qty: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Product {
|
||||
pub fn to_db(p: &Product) -> String {
|
||||
let image: String = hex::encode(&p.image);
|
||||
format!(
|
||||
"{}:{}:{}:{}:{}:{}",
|
||||
p.description, image, p.in_stock, p.name, p.price, p.qty
|
||||
)
|
||||
}
|
||||
pub fn from_db(k: String, v: String) -> Product {
|
||||
let values = v.split(":");
|
||||
let mut v: Vec<String> = values.map(String::from).collect();
|
||||
let description = v.remove(0);
|
||||
let image = hex::decode(v.remove(0)).unwrap_or_default();
|
||||
let in_stock = v.remove(0).parse::<bool>().unwrap_or(false);
|
||||
let name = v.remove(0);
|
||||
let price = v.remove(0).parse::<u128>().unwrap_or(0);
|
||||
let qty = v.remove(0).parse::<u128>().unwrap_or(0);
|
||||
Product {
|
||||
pid: k,
|
||||
description,
|
||||
image,
|
||||
in_stock,
|
||||
name,
|
||||
price,
|
||||
qty,
|
||||
}
|
||||
}
|
||||
pub fn update(p: Product, jp: &Json<Product>) -> Product {
|
||||
Product {
|
||||
pid: p.pid,
|
||||
|
@ -294,7 +111,7 @@ impl Product {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||
#[serde(crate = "rocket::serde")]
|
||||
pub struct Order {
|
||||
pub orid: String,
|
||||
|
@ -332,140 +149,7 @@ pub struct Order {
|
|||
pub xmr_address: String,
|
||||
}
|
||||
|
||||
impl Default for Order {
|
||||
fn default() -> Self {
|
||||
Order {
|
||||
orid: utils::empty_string(),
|
||||
cid: utils::empty_string(),
|
||||
pid: utils::empty_string(),
|
||||
xmr_address: utils::empty_string(),
|
||||
cust_kex_1: utils::empty_string(),
|
||||
cust_kex_2: utils::empty_string(),
|
||||
cust_kex_3: utils::empty_string(),
|
||||
cust_msig_make: utils::empty_string(),
|
||||
cust_msig_prepare: utils::empty_string(),
|
||||
cust_msig_txset: utils::empty_string(),
|
||||
date: 0,
|
||||
deliver_date: 0,
|
||||
hash: utils::empty_string(),
|
||||
adjudicator_kex_1: utils::empty_string(),
|
||||
adjudicator_kex_2: utils::empty_string(),
|
||||
adjudicator_kex_3: utils::empty_string(),
|
||||
adjudicator_msig_make: utils::empty_string(),
|
||||
adjudicator_msig_prepare: utils::empty_string(),
|
||||
ship_address: utils::empty_string(),
|
||||
ship_date: 0,
|
||||
subaddress: utils::empty_string(),
|
||||
status: utils::empty_string(),
|
||||
quantity: 0,
|
||||
vend_kex_1: utils::empty_string(),
|
||||
vend_kex_2: utils::empty_string(),
|
||||
vend_kex_3: utils::empty_string(),
|
||||
vend_msig_make: utils::empty_string(),
|
||||
vend_msig_prepare: utils::empty_string(),
|
||||
vend_msig_txset: utils::empty_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Order {
|
||||
pub fn to_db(o: &Order) -> String {
|
||||
format!(
|
||||
"{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}",
|
||||
o.cid,
|
||||
o.pid,
|
||||
o.cust_kex_1,
|
||||
o.cust_kex_2,
|
||||
o.cust_kex_3,
|
||||
o.cust_msig_make,
|
||||
o.cust_msig_prepare,
|
||||
o.cust_msig_txset,
|
||||
o.date,
|
||||
o.deliver_date,
|
||||
o.hash,
|
||||
o.adjudicator_msig_make,
|
||||
o.adjudicator_msig_prepare,
|
||||
o.adjudicator_kex_1,
|
||||
o.adjudicator_kex_2,
|
||||
o.adjudicator_kex_3,
|
||||
o.ship_address,
|
||||
o.ship_date,
|
||||
o.subaddress,
|
||||
o.status,
|
||||
o.quantity,
|
||||
o.vend_kex_1,
|
||||
o.vend_kex_2,
|
||||
o.vend_kex_3,
|
||||
o.vend_msig_make,
|
||||
o.vend_msig_prepare,
|
||||
o.vend_msig_txset,
|
||||
o.xmr_address,
|
||||
)
|
||||
}
|
||||
pub fn from_db(k: String, v: String) -> Order {
|
||||
let values = v.split(":");
|
||||
let mut v: Vec<String> = values.map(String::from).collect();
|
||||
let orid = k;
|
||||
let cid = v.remove(0);
|
||||
let pid = v.remove(0);
|
||||
let cust_kex_1 = v.remove(0);
|
||||
let cust_kex_2 = v.remove(0);
|
||||
let cust_kex_3 = v.remove(0);
|
||||
let cust_msig_make = v.remove(0);
|
||||
let cust_msig_prepare = v.remove(0);
|
||||
let cust_msig_txset = v.remove(0);
|
||||
let date = v.remove(0).parse::<i64>().unwrap_or(0);
|
||||
let deliver_date = v.remove(0).parse::<i64>().unwrap_or(0);
|
||||
let hash = v.remove(0);
|
||||
let adjudicator_msig_make = v.remove(0);
|
||||
let adjudicator_msig_prepare = v.remove(0);
|
||||
let adjudicator_kex_1 = v.remove(0);
|
||||
let adjudicator_kex_2 = v.remove(0);
|
||||
let adjudicator_kex_3 = v.remove(0);
|
||||
let ship_address = v.remove(0);
|
||||
let ship_date = v.remove(0).parse::<i64>().unwrap_or(0);
|
||||
let subaddress = v.remove(0);
|
||||
let status = v.remove(0);
|
||||
let quantity = v.remove(0).parse::<u128>().unwrap_or(0);
|
||||
let vend_kex_1 = v.remove(0);
|
||||
let vend_kex_2 = v.remove(0);
|
||||
let vend_kex_3 = v.remove(0);
|
||||
let vend_msig_make = v.remove(0);
|
||||
let vend_msig_prepare = v.remove(0);
|
||||
let vend_msig_txset = v.remove(0);
|
||||
let xmr_address = v.remove(0);
|
||||
Order {
|
||||
orid,
|
||||
cid,
|
||||
pid,
|
||||
cust_kex_1,
|
||||
cust_kex_2,
|
||||
cust_kex_3,
|
||||
cust_msig_make,
|
||||
cust_msig_prepare,
|
||||
cust_msig_txset,
|
||||
date,
|
||||
deliver_date,
|
||||
hash,
|
||||
adjudicator_kex_1,
|
||||
adjudicator_kex_2,
|
||||
adjudicator_kex_3,
|
||||
adjudicator_msig_make,
|
||||
adjudicator_msig_prepare,
|
||||
ship_address,
|
||||
ship_date,
|
||||
subaddress,
|
||||
status,
|
||||
quantity,
|
||||
vend_kex_1,
|
||||
vend_kex_2,
|
||||
vend_kex_3,
|
||||
vend_msig_make,
|
||||
vend_msig_prepare,
|
||||
vend_msig_txset,
|
||||
xmr_address,
|
||||
}
|
||||
}
|
||||
pub fn update(orid: String, o: &Json<Order>) -> Order {
|
||||
Order {
|
||||
orid,
|
||||
|
@ -501,7 +185,7 @@ impl Order {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||
#[serde(crate = "rocket::serde")]
|
||||
pub struct Dispute {
|
||||
pub did: String,
|
||||
|
@ -509,33 +193,3 @@ pub struct Dispute {
|
|||
pub orid: String,
|
||||
pub tx_set: String,
|
||||
}
|
||||
|
||||
impl Default for Dispute {
|
||||
fn default() -> Self {
|
||||
Dispute {
|
||||
did: utils::empty_string(),
|
||||
created: 0,
|
||||
orid: utils::empty_string(),
|
||||
tx_set: utils::empty_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Dispute {
|
||||
pub fn to_db(d: &Dispute) -> String {
|
||||
format!("{}:{}:{}", d.created, d.orid, d.tx_set)
|
||||
}
|
||||
pub fn from_db(k: String, v: String) -> Dispute {
|
||||
let values = v.split(":");
|
||||
let mut v: Vec<String> = values.map(String::from).collect();
|
||||
let created = v.remove(0).parse::<i64>().unwrap_or(0);
|
||||
let orid = v.remove(0);
|
||||
let tx_set = v.remove(0);
|
||||
Dispute {
|
||||
did: k,
|
||||
created,
|
||||
orid,
|
||||
tx_set,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -319,15 +319,15 @@ fn get_blockchain_dir() -> String {
|
|||
/// Get monero download location
|
||||
fn get_monero_location() -> String {
|
||||
let args = args::Args::parse();
|
||||
let user = std::env::var("USER").unwrap_or(utils::empty_string());
|
||||
let user = std::env::var("USER").unwrap_or(String::new());
|
||||
format!("/home/{}/{}", &user, &args.monero_location)
|
||||
}
|
||||
|
||||
/// Get monero rpc host from the `--monero-rpc-host` cli arg
|
||||
fn get_rpc_host() -> String {
|
||||
let args = args::Args::parse();
|
||||
let gui_host = std::env::var(crate::MONERO_WALLET_RPC_HOST).unwrap_or(utils::empty_string());
|
||||
let rpc = if gui_host == utils::empty_string() {
|
||||
let gui_host = std::env::var(crate::MONERO_WALLET_RPC_HOST).unwrap_or(String::new());
|
||||
let rpc = if gui_host.is_empty() {
|
||||
args.monero_rpc_host
|
||||
} else {
|
||||
gui_host
|
||||
|
@ -348,8 +348,8 @@ fn get_rpc_creds() -> RpcLogin {
|
|||
|
||||
fn get_rpc_daemon() -> String {
|
||||
let args = args::Args::parse();
|
||||
let gui_host = std::env::var(crate::MONERO_DAEMON_HOST).unwrap_or(utils::empty_string());
|
||||
if gui_host == utils::empty_string() {
|
||||
let gui_host = std::env::var(crate::MONERO_DAEMON_HOST).unwrap_or(String::new());
|
||||
if gui_host.is_empty() {
|
||||
args.monero_rpc_daemon
|
||||
} else {
|
||||
gui_host
|
||||
|
|
|
@ -15,11 +15,7 @@ use sha2::{
|
|||
Digest,
|
||||
Sha512,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
monero,
|
||||
utils,
|
||||
};
|
||||
use crate::monero;
|
||||
|
||||
#[derive(Debug)]
|
||||
/// Container for the Neveko Message Keys
|
||||
|
@ -39,8 +35,8 @@ impl Default for NevekoMessageKeys {
|
|||
NevekoMessageKeys {
|
||||
nmpk: [0u8; 32],
|
||||
nmsk: [0u8; 32],
|
||||
hex_nmpk: utils::empty_string(),
|
||||
hex_nmsk: utils::empty_string(),
|
||||
hex_nmpk: String::new(),
|
||||
hex_nmsk: String::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -96,7 +92,7 @@ fn hash_to_scalar(s: Vec<&str>) -> Scalar {
|
|||
/// Neveko Message Public Key (NMPK).
|
||||
pub async fn generate_neveko_message_keys() -> NevekoMessageKeys {
|
||||
log::info!("generating neveko message keys");
|
||||
let password = std::env::var(crate::MONERO_WALLET_PASSWORD).unwrap_or(utils::empty_string());
|
||||
let password = std::env::var(crate::MONERO_WALLET_PASSWORD).unwrap_or(String::new());
|
||||
let filename = String::from(crate::APP_NAME);
|
||||
let m_wallet = monero::open_wallet(&filename, &password).await;
|
||||
if !m_wallet {
|
||||
|
@ -130,7 +126,7 @@ pub async fn generate_neveko_message_keys() -> NevekoMessageKeys {
|
|||
///
|
||||
/// Pass `None` to encipher parameter to perform deciphering.
|
||||
pub async fn cipher(hex_nmpk: &String, message: String, encipher: Option<String>) -> String {
|
||||
let unwrap_encipher: String = encipher.unwrap_or(utils::empty_string());
|
||||
let unwrap_encipher: String = encipher.unwrap_or(String::new());
|
||||
let keys: NevekoMessageKeys = generate_neveko_message_keys().await;
|
||||
// shared secret = nmpk * nmsk
|
||||
let scalar_nmsk = Scalar::from_bytes_mod_order(keys.nmsk);
|
||||
|
@ -162,7 +158,7 @@ mod tests {
|
|||
use super::*;
|
||||
|
||||
fn test_cipher(message: &String, encipher: Option<String>) -> String {
|
||||
let unwrap_encipher: String = encipher.unwrap_or(utils::empty_string());
|
||||
let unwrap_encipher: String = encipher.unwrap_or(String::new());
|
||||
let test_nmpk: [u8; 32] = [
|
||||
203, 2, 188, 13, 167, 96, 59, 189, 38, 238, 2, 71, 84, 155, 153, 73, 241, 137, 9, 30,
|
||||
28, 134, 91, 137, 134, 73, 231, 45, 174, 98, 103, 158,
|
||||
|
|
|
@ -65,7 +65,7 @@ pub async fn create(j_order: Json<reqres::OrderRequest>) -> Order {
|
|||
..Default::default()
|
||||
};
|
||||
debug!("insert order: {:?}", new_order);
|
||||
let order_wallet_password = utils::empty_string();
|
||||
let order_wallet_password = String::new();
|
||||
let m_wallet = monero::create_wallet(&orid, &order_wallet_password).await;
|
||||
if !m_wallet {
|
||||
error!("error creating msig wallet for order {}", &orid);
|
||||
|
@ -74,35 +74,35 @@ pub async fn create(j_order: Json<reqres::OrderRequest>) -> Order {
|
|||
}
|
||||
monero::close_wallet(&orid, &order_wallet_password).await;
|
||||
debug!("insert order: {:?}", &new_order);
|
||||
let s = db::Interface::async_open().await;
|
||||
let s = db::DatabaseEnvironment::async_open().await;
|
||||
// inject adjudicator separately, modifying the order model is mendokusai
|
||||
let adjudicator_k = format!("{}-{}", crate::ADJUDICATOR_DB_KEY, &orid);
|
||||
db::Interface::async_write(&s.env, &s.handle, &adjudicator_k, &j_order.adjudicator).await;
|
||||
db::DatabaseEnvironment::async_write(&s.env, &s.handle, &adjudicator_k, &j_order.adjudicator).await;
|
||||
let k = &new_order.orid;
|
||||
db::Interface::async_write(&s.env, &s.handle, k, &Order::to_db(&new_order)).await;
|
||||
db::DatabaseEnvironment::async_write(&s.env, &s.handle, k, &Order::to_db(&new_order)).await;
|
||||
// in order to retrieve all orders, write keys to with ol
|
||||
let list_key = crate::ORDER_LIST_DB_KEY;
|
||||
let r = db::Interface::async_read(&s.env, &s.handle, &String::from(list_key)).await;
|
||||
if r == utils::empty_string() {
|
||||
let r = db::DatabaseEnvironment::async_read(&s.env, &s.handle, &String::from(list_key)).await;
|
||||
if r.is_empty() {
|
||||
debug!("creating order index");
|
||||
}
|
||||
let order_list = [r, String::from(&orid)].join(",");
|
||||
debug!("writing order index {} for id: {}", order_list, list_key);
|
||||
db::Interface::async_write(&s.env, &s.handle, &String::from(list_key), &order_list).await;
|
||||
db::DatabaseEnvironment::async_write(&s.env, &s.handle, &String::from(list_key), &order_list).await;
|
||||
new_order
|
||||
}
|
||||
|
||||
/// Backup order for customer
|
||||
pub fn backup(order: &Order) {
|
||||
info!("creating backup of order: {}", order.orid);
|
||||
let s = db::Interface::open();
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
let k = &order.orid;
|
||||
db::Interface::delete(&s.env, &s.handle, k);
|
||||
db::Interface::write(&s.env, &s.handle, k, &Order::to_db(order));
|
||||
db::DatabaseEnvironment::delete(&s.env, &s.handle, k);
|
||||
db::DatabaseEnvironment::write(&s.env, &s.handle, k, &Order::to_db(order));
|
||||
// in order to retrieve all orders, write keys to with col
|
||||
let list_key = crate::CUSTOMER_ORDER_LIST_DB_KEY;
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
||||
if r == utils::empty_string() {
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, &String::from(list_key));
|
||||
if r.is_empty() {
|
||||
debug!("creating customer order index");
|
||||
}
|
||||
let mut order_list = [String::from(&r), String::from(&order.orid)].join(",");
|
||||
|
@ -111,15 +111,15 @@ pub fn backup(order: &Order) {
|
|||
order_list = r;
|
||||
}
|
||||
debug!("writing order index {} for id: {}", order_list, list_key);
|
||||
db::Interface::write(&s.env, &s.handle, &String::from(list_key), &order_list);
|
||||
db::DatabaseEnvironment::write(&s.env, &s.handle, &String::from(list_key), &order_list);
|
||||
}
|
||||
|
||||
/// Lookup order
|
||||
pub fn find(oid: &String) -> Order {
|
||||
info!("find order: {}", &oid);
|
||||
let s = db::Interface::open();
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(oid));
|
||||
if r == utils::empty_string() {
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, &String::from(oid));
|
||||
if r.is_empty() {
|
||||
error!("order not found");
|
||||
return Default::default();
|
||||
}
|
||||
|
@ -128,10 +128,10 @@ pub fn find(oid: &String) -> Order {
|
|||
|
||||
/// Lookup all orders from admin server
|
||||
pub fn find_all() -> Vec<Order> {
|
||||
let i_s = db::Interface::open();
|
||||
let i_s = db::DatabaseEnvironment::open();
|
||||
let i_list_key = crate::ORDER_LIST_DB_KEY;
|
||||
let i_r = db::Interface::read(&i_s.env, &i_s.handle, &String::from(i_list_key));
|
||||
if i_r == utils::empty_string() {
|
||||
let i_r = db::DatabaseEnvironment::read(&i_s.env, &i_s.handle, &String::from(i_list_key));
|
||||
if i_r.is_empty() {
|
||||
error!("order index not found");
|
||||
}
|
||||
let i_v_oid = i_r.split(",");
|
||||
|
@ -139,7 +139,7 @@ pub fn find_all() -> Vec<Order> {
|
|||
let mut orders: Vec<Order> = Vec::new();
|
||||
for o in i_v {
|
||||
let order: Order = find(&o);
|
||||
if order.orid != utils::empty_string() {
|
||||
if !order.orid.is_empty() {
|
||||
orders.push(order);
|
||||
}
|
||||
}
|
||||
|
@ -148,10 +148,10 @@ pub fn find_all() -> Vec<Order> {
|
|||
|
||||
/// Lookup all orders that customer has saved from gui
|
||||
pub fn find_all_backup() -> Vec<Order> {
|
||||
let i_s = db::Interface::open();
|
||||
let i_s = db::DatabaseEnvironment::open();
|
||||
let i_list_key = crate::CUSTOMER_ORDER_LIST_DB_KEY;
|
||||
let i_r = db::Interface::read(&i_s.env, &i_s.handle, &String::from(i_list_key));
|
||||
if i_r == utils::empty_string() {
|
||||
let i_r = db::DatabaseEnvironment::read(&i_s.env, &i_s.handle, &String::from(i_list_key));
|
||||
if i_r.is_empty() {
|
||||
error!("customer order index not found");
|
||||
}
|
||||
let i_v_oid = i_r.split(",");
|
||||
|
@ -159,7 +159,7 @@ pub fn find_all_backup() -> Vec<Order> {
|
|||
let mut orders: Vec<Order> = Vec::new();
|
||||
for o in i_v {
|
||||
let order: Order = find(&o);
|
||||
let visible = order.orid != utils::empty_string()
|
||||
let visible = !order.orid.is_empty()
|
||||
&& order.status != order::StatusType::Delivered.value()
|
||||
&& order.status != order::StatusType::Cancelled.value();
|
||||
if visible {
|
||||
|
@ -172,10 +172,10 @@ pub fn find_all_backup() -> Vec<Order> {
|
|||
/// Lookup all orders for customer
|
||||
pub async fn find_all_customer_orders(cid: String) -> Vec<Order> {
|
||||
info!("lookup orders for customer: {}", &cid);
|
||||
let i_s = db::Interface::open();
|
||||
let i_s = db::DatabaseEnvironment::open();
|
||||
let i_list_key = crate::ORDER_LIST_DB_KEY;
|
||||
let i_r = db::Interface::read(&i_s.env, &i_s.handle, &String::from(i_list_key));
|
||||
if i_r == utils::empty_string() {
|
||||
let i_r = db::DatabaseEnvironment::read(&i_s.env, &i_s.handle, &String::from(i_list_key));
|
||||
if i_r.is_empty() {
|
||||
error!("order index not found");
|
||||
}
|
||||
let i_v_oid = i_r.split(",");
|
||||
|
@ -183,7 +183,7 @@ pub async fn find_all_customer_orders(cid: String) -> Vec<Order> {
|
|||
let mut orders: Vec<Order> = Vec::new();
|
||||
for o in i_v {
|
||||
let order: Order = find(&o);
|
||||
if order.orid != utils::empty_string() && order.cid == cid {
|
||||
if !order.orid.is_empty() && order.cid == cid {
|
||||
orders.push(order);
|
||||
}
|
||||
}
|
||||
|
@ -193,10 +193,10 @@ pub async fn find_all_customer_orders(cid: String) -> Vec<Order> {
|
|||
/// Lookup all orders for vendor
|
||||
pub fn find_all_vendor_orders() -> Vec<Order> {
|
||||
info!("lookup orders for vendor");
|
||||
let i_s = db::Interface::open();
|
||||
let i_s = db::DatabaseEnvironment::open();
|
||||
let i_list_key = crate::ORDER_LIST_DB_KEY;
|
||||
let i_r = db::Interface::read(&i_s.env, &i_s.handle, &String::from(i_list_key));
|
||||
if i_r == utils::empty_string() {
|
||||
let i_r = db::DatabaseEnvironment::read(&i_s.env, &i_s.handle, &String::from(i_list_key));
|
||||
if i_r.is_empty() {
|
||||
error!("order index not found");
|
||||
}
|
||||
let i_v_oid = i_r.split(",");
|
||||
|
@ -205,7 +205,7 @@ pub fn find_all_vendor_orders() -> Vec<Order> {
|
|||
let vendor_b32: String = i2p::get_destination(None);
|
||||
for o in i_v {
|
||||
let order: Order = find(&o);
|
||||
if order.orid != utils::empty_string() && order.cid != vendor_b32 {
|
||||
if !order.orid.is_empty() && order.cid != vendor_b32 {
|
||||
// TODO(c2m): separate functionality for archived orders
|
||||
if order.status != order::StatusType::Cancelled.value()
|
||||
&& order.status != order::StatusType::Delivered.value()
|
||||
|
@ -221,14 +221,14 @@ pub fn find_all_vendor_orders() -> Vec<Order> {
|
|||
pub fn modify(o: Json<Order>) -> Order {
|
||||
info!("modify order: {}", &o.orid);
|
||||
let f_order: Order = find(&o.orid);
|
||||
if f_order.orid == utils::empty_string() {
|
||||
if f_order.orid.is_empty() {
|
||||
error!("order not found");
|
||||
return Default::default();
|
||||
}
|
||||
let u_order = Order::update(String::from(&f_order.orid), &o);
|
||||
let s = db::Interface::open();
|
||||
db::Interface::delete(&s.env, &s.handle, &u_order.orid);
|
||||
db::Interface::write(&s.env, &s.handle, &u_order.orid, &Order::to_db(&u_order));
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
db::DatabaseEnvironment::delete(&s.env, &s.handle, &u_order.orid);
|
||||
db::DatabaseEnvironment::write(&s.env, &s.handle, &u_order.orid, &Order::to_db(&u_order));
|
||||
u_order
|
||||
}
|
||||
|
||||
|
@ -238,7 +238,7 @@ pub async fn sign_and_submit_multisig(
|
|||
tx_data_hex: &String,
|
||||
) -> reqres::XmrRpcSubmitMultisigResponse {
|
||||
info!("signing and submitting multisig");
|
||||
let wallet_password = utils::empty_string();
|
||||
let wallet_password = String::new();
|
||||
monero::open_wallet(orid, &wallet_password).await;
|
||||
let r_sign: reqres::XmrRpcSignMultisigResponse =
|
||||
monero::sign_multisig(String::from(tx_data_hex)).await;
|
||||
|
@ -327,14 +327,14 @@ pub async fn validate_order_for_ship(orid: &String) -> reqres::FinalizeOrderResp
|
|||
let m_order: Order = find(orid);
|
||||
let contact: Contact = contact::find(&m_order.cid);
|
||||
let hex_nmpk: String = contact.nmpk;
|
||||
let s = db::Interface::async_open().await;
|
||||
let s = db::DatabaseEnvironment::async_open().await;
|
||||
let k = String::from(crate::DELIVERY_INFO_DB_KEY);
|
||||
let delivery_info: String = db::Interface::async_read(&s.env, &s.handle, &k).await;
|
||||
let delivery_info: String = db::DatabaseEnvironment::async_read(&s.env, &s.handle, &k).await;
|
||||
let mut j_order: Order = find(orid);
|
||||
let m_product: Product = product::find(&m_order.pid);
|
||||
let price = m_product.price;
|
||||
let total = price * &m_order.quantity;
|
||||
let wallet_password = utils::empty_string();
|
||||
let wallet_password = String::new();
|
||||
monero::open_wallet(orid, &wallet_password).await;
|
||||
// check balance and unlock_time
|
||||
let r_balance = monero::get_balance().await;
|
||||
|
@ -420,7 +420,7 @@ pub async fn upload_delivery_info(
|
|||
error!("unable to encipher delivery info");
|
||||
}
|
||||
// get draft payment txset
|
||||
let wallet_password = utils::empty_string();
|
||||
let wallet_password = String::new();
|
||||
monero::open_wallet(orid, &wallet_password).await;
|
||||
monero::refresh().await;
|
||||
let sweep: reqres::XmrRpcSweepAllResponse =
|
||||
|
@ -437,17 +437,17 @@ pub async fn upload_delivery_info(
|
|||
m_order.vend_msig_txset = sweep.result.multisig_txset;
|
||||
// delivery info will be stored enciphered and separate from the rest of the
|
||||
// order
|
||||
let s = db::Interface::async_open().await;
|
||||
let s = db::DatabaseEnvironment::async_open().await;
|
||||
let k = String::from(crate::DELIVERY_INFO_DB_KEY);
|
||||
db::Interface::async_write(&s.env, &s.handle, &k, &hex::encode(delivery_info)).await;
|
||||
db::DatabaseEnvironment::async_write(&s.env, &s.handle, &k, &hex::encode(delivery_info)).await;
|
||||
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);
|
||||
let s = db::Interface::open();
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
// get jwp from db
|
||||
let k = format!("{}-{}", crate::FTS_JWP_DB_KEY, &lookup.cid);
|
||||
let jwp = db::Interface::read(&s.env, &s.handle, &k);
|
||||
let jwp = db::DatabaseEnvironment::read(&s.env, &s.handle, &k);
|
||||
let nasr_order = trigger_nasr(&lookup.cid, &i2p_address, &jwp, orid).await;
|
||||
if nasr_order.is_err() {
|
||||
return Default::default();
|
||||
|
@ -468,12 +468,12 @@ pub async fn finalize_order(orid: &String) -> reqres::FinalizeOrderResponse {
|
|||
info!("finalizing order: {}", orid);
|
||||
// verify recipient and unlock time
|
||||
let mut m_order: Order = order::find(orid);
|
||||
if m_order.vend_msig_txset == utils::empty_string() {
|
||||
if m_order.vend_msig_txset.is_empty() {
|
||||
error!("txset missing");
|
||||
return Default::default();
|
||||
}
|
||||
// get draft payment txset
|
||||
let wallet_password = utils::empty_string();
|
||||
let wallet_password = String::new();
|
||||
monero::open_wallet(orid, &wallet_password).await;
|
||||
monero::refresh().await;
|
||||
let address: String = String::from(&m_order.subaddress);
|
||||
|
@ -573,9 +573,9 @@ pub async fn d_trigger_finalize_request(
|
|||
) -> reqres::FinalizeOrderResponse {
|
||||
// ugh, sorry seems we need to get jwp for vendor from fts cache
|
||||
// get jwp from db
|
||||
let s = db::Interface::async_open().await;
|
||||
let s = db::DatabaseEnvironment::async_open().await;
|
||||
let k = format!("{}-{}", crate::FTS_JWP_DB_KEY, &contact);
|
||||
let jwp = db::Interface::async_read(&s.env, &s.handle, &k).await;
|
||||
let jwp = db::DatabaseEnvironment::async_read(&s.env, &s.handle, &k).await;
|
||||
info!("executing d_trigger_finalize_request");
|
||||
// request finalize if the order status is shipped
|
||||
let order: Order = order::find(orid);
|
||||
|
@ -738,9 +738,9 @@ pub async fn trigger_cancel_request(contact: &String, jwp: &String, orid: &Strin
|
|||
pub async fn d_trigger_ship_request(contact: &String, orid: &String) -> Order {
|
||||
// ugh, sorry seems we need to get jwp for vendor from fts cache
|
||||
// get jwp from db
|
||||
let s = db::Interface::async_open().await;
|
||||
let s = db::DatabaseEnvironment::async_open().await;
|
||||
let k = format!("{}-{}", crate::FTS_JWP_DB_KEY, &contact);
|
||||
let jwp = db::Interface::async_read(&s.env, &s.handle, &k).await;
|
||||
let jwp = db::DatabaseEnvironment::async_read(&s.env, &s.handle, &k).await;
|
||||
info!("executing d_trigger_ship_request");
|
||||
// request shipment if the order status is MultisigComplete
|
||||
let trigger = trigger_ship_request(contact, &jwp, orid).await;
|
||||
|
@ -753,7 +753,7 @@ pub async fn d_trigger_ship_request(contact: &String, orid: &String) -> Order {
|
|||
let u_ship_res = ship_res.unwrap_or(Default::default());
|
||||
let hex_delivery_info: String = hex::encode(u_ship_res.delivery_info);
|
||||
let key = format!("{}-{}", crate::DELIVERY_INFO_DB_KEY, orid);
|
||||
db::Interface::write(&s.env, &s.handle, &key, &hex_delivery_info);
|
||||
db::DatabaseEnvironment::write(&s.env, &s.handle, &key, &hex_delivery_info);
|
||||
}
|
||||
trigger
|
||||
}
|
||||
|
@ -803,9 +803,9 @@ pub async fn transmit_cancel_request(
|
|||
pub async fn d_trigger_cancel_request(contact: &String, orid: &String) -> Order {
|
||||
// ugh, sorry seems we need to get jwp for vendor from fts cache
|
||||
// get jwp from db
|
||||
let s = db::Interface::async_open().await;
|
||||
let s = db::DatabaseEnvironment::async_open().await;
|
||||
let k = format!("{}-{}", crate::FTS_JWP_DB_KEY, &contact);
|
||||
let jwp = db::Interface::async_read(&s.env, &s.handle, &k).await;
|
||||
let jwp = db::DatabaseEnvironment::async_read(&s.env, &s.handle, &k).await;
|
||||
info!("executing d_trigger_cancel_request");
|
||||
// request cancel if the order status is not MultisigComplete
|
||||
let order: Order = order::find(orid);
|
||||
|
@ -819,7 +819,7 @@ pub async fn d_trigger_cancel_request(contact: &String, orid: &String) -> Order
|
|||
}
|
||||
|
||||
pub async fn init_adjudicator_wallet(orid: &String) {
|
||||
let password = utils::empty_string();
|
||||
let password = String::new();
|
||||
let m_wallet = monero::create_wallet(orid, &password).await;
|
||||
if !m_wallet {
|
||||
log::error!("failed to create adjudicator wallet");
|
||||
|
|
|
@ -30,13 +30,13 @@ pub fn create(d: Json<Product>) -> Product {
|
|||
qty: d.qty,
|
||||
};
|
||||
debug!("insert product: {:?}", &new_product);
|
||||
let s = db::Interface::open();
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
let k = &new_product.pid;
|
||||
db::Interface::write(&s.env, &s.handle, k, &Product::to_db(&new_product));
|
||||
db::DatabaseEnvironment::write(&s.env, &s.handle, k, &Product::to_db(&new_product));
|
||||
// in order to retrieve all products, write keys to with pl
|
||||
let list_key = crate::PRODUCT_LIST_DB_KEY;
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
||||
if r == utils::empty_string() {
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, &String::from(list_key));
|
||||
if r.is_empty() {
|
||||
debug!("creating product index");
|
||||
}
|
||||
let product_list = [r, String::from(&pid)].join(",");
|
||||
|
@ -44,15 +44,15 @@ pub fn create(d: Json<Product>) -> Product {
|
|||
"writing product index {} for id: {}",
|
||||
product_list, list_key
|
||||
);
|
||||
db::Interface::write(&s.env, &s.handle, &String::from(list_key), &product_list);
|
||||
db::DatabaseEnvironment::write(&s.env, &s.handle, &String::from(list_key), &product_list);
|
||||
new_product
|
||||
}
|
||||
|
||||
/// Single Product lookup
|
||||
pub fn find(pid: &String) -> Product {
|
||||
let s = db::Interface::open();
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(pid));
|
||||
if r == utils::empty_string() {
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, &String::from(pid));
|
||||
if r.is_empty() {
|
||||
error!("product not found");
|
||||
return Default::default();
|
||||
}
|
||||
|
@ -61,10 +61,10 @@ pub fn find(pid: &String) -> Product {
|
|||
|
||||
/// Product lookup for all
|
||||
pub fn find_all() -> Vec<Product> {
|
||||
let i_s = db::Interface::open();
|
||||
let i_s = db::DatabaseEnvironment::open();
|
||||
let i_list_key = crate::PRODUCT_LIST_DB_KEY;
|
||||
let i_r = db::Interface::read(&i_s.env, &i_s.handle, &String::from(i_list_key));
|
||||
if i_r == utils::empty_string() {
|
||||
let i_r = db::DatabaseEnvironment::read(&i_s.env, &i_s.handle, &String::from(i_list_key));
|
||||
if i_r.is_empty() {
|
||||
error!("product index not found");
|
||||
}
|
||||
let i_v_pid = i_r.split(",");
|
||||
|
@ -72,7 +72,7 @@ pub fn find_all() -> Vec<Product> {
|
|||
let mut products: Vec<Product> = Vec::new();
|
||||
for p in i_v {
|
||||
let mut product: Product = find(&p);
|
||||
if product.pid != utils::empty_string() {
|
||||
if !product.pid.is_empty() {
|
||||
// don't return images
|
||||
product.image = Vec::new();
|
||||
products.push(product);
|
||||
|
@ -86,14 +86,14 @@ pub fn modify(p: Json<Product>) -> Product {
|
|||
// 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 == utils::empty_string() {
|
||||
if f_prod.pid.is_empty() {
|
||||
error!("product not found");
|
||||
return Default::default();
|
||||
}
|
||||
let u_prod = Product::update(f_prod, &p);
|
||||
let s = db::Interface::open();
|
||||
db::Interface::delete(&s.env, &s.handle, &u_prod.pid);
|
||||
db::Interface::write(&s.env, &s.handle, &u_prod.pid, &Product::to_db(&u_prod));
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
db::DatabaseEnvironment::delete(&s.env, &s.handle, &u_prod.pid);
|
||||
db::DatabaseEnvironment::write(&s.env, &s.handle, &u_prod.pid, &Product::to_db(&u_prod));
|
||||
u_prod
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ use serde::{
|
|||
use sha2::Sha512;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||
pub struct TxProof {
|
||||
pub subaddress: String,
|
||||
pub confirmations: u64,
|
||||
|
@ -40,18 +40,6 @@ pub struct TxProof {
|
|||
pub signature: String,
|
||||
}
|
||||
|
||||
impl Default for TxProof {
|
||||
fn default() -> Self {
|
||||
TxProof {
|
||||
subaddress: utils::empty_string(),
|
||||
confirmations: 0,
|
||||
hash: utils::empty_string(),
|
||||
message: utils::empty_string(),
|
||||
signature: utils::empty_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Provide neccessary information for contacts to
|
||||
///
|
||||
/// provide proof of payment.
|
||||
|
@ -89,9 +77,9 @@ pub async fn create_jwp(proof: &TxProof) -> String {
|
|||
info!("creating jwp");
|
||||
// validate the proof
|
||||
let c_txp: TxProof = validate_proof(proof).await;
|
||||
if c_txp.hash == utils::empty_string() {
|
||||
if c_txp.hash.is_empty() {
|
||||
error!("invalid transaction proof");
|
||||
return utils::empty_string();
|
||||
return String::new();
|
||||
}
|
||||
let jwp_secret_key = utils::get_jwp_secret_key();
|
||||
let key: Hmac<Sha512> = Hmac::new_from_slice(jwp_secret_key.as_bytes()).expect("hash");
|
||||
|
@ -134,10 +122,12 @@ pub async fn prove_payment(contact: String, txp: &TxProof) -> Result<reqres::Jwp
|
|||
match res {
|
||||
Ok(r) => {
|
||||
// cache the jwp for for fts
|
||||
let s = db::Interface::open();
|
||||
let env = utils::get_release_env();
|
||||
let s = db::DatabaseEnvironment::open(&env.value())?;
|
||||
let k = format!("{}-{}", crate::FTS_JWP_DB_KEY, &contact);
|
||||
db::Interface::delete(&s.env, &s.handle, &k);
|
||||
db::Interface::write(&s.env, &s.handle, &k, &r.jwp);
|
||||
db::DatabaseEnvironment::delete(&s.env, &s.handle?, k.as_bytes())?;
|
||||
let s = db::DatabaseEnvironment::open(&env.value())?;
|
||||
db::write_chunks(&s.env, &s.handle?, &k.as_bytes(), &r.jwp.as_bytes().to_vec());
|
||||
Ok(r)
|
||||
}
|
||||
_ => Ok(Default::default()),
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -6,52 +6,40 @@ use crate::{
|
|||
models::*,
|
||||
utils,
|
||||
};
|
||||
use kn0sys_lmdb_rs::MdbError;
|
||||
use log::{
|
||||
debug,
|
||||
error,
|
||||
info,
|
||||
};
|
||||
use rocket::serde::json::Json;
|
||||
|
||||
/// Create a new user
|
||||
pub fn create(address: &String) -> User {
|
||||
pub fn create(address: &String) -> Result<User, MdbError> {
|
||||
let f_uid: String = format!("{}{}", crate::USER_DB_KEY, utils::generate_rnd());
|
||||
let new_user = User {
|
||||
uid: String::from(&f_uid),
|
||||
xmr_address: String::from(address),
|
||||
name: utils::empty_string(),
|
||||
name: String::new(),
|
||||
};
|
||||
debug!("insert user: {:?}", &new_user);
|
||||
let s = db::Interface::open();
|
||||
let env = utils::get_release_env();
|
||||
let s = db::DatabaseEnvironment::open(&env.value())?;
|
||||
let k = &new_user.uid;
|
||||
db::Interface::write(&s.env, &s.handle, k, &User::to_db(&new_user));
|
||||
new_user
|
||||
let v = bincode::serialize(&new_user).unwrap_or_default();
|
||||
db::write_chunks(&s.env, &s.handle?, k.as_bytes(), &v)?;
|
||||
Ok(new_user)
|
||||
}
|
||||
|
||||
/// User lookup
|
||||
pub fn find(uid: &String) -> User {
|
||||
let s = db::Interface::open();
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(uid));
|
||||
if r == utils::empty_string() {
|
||||
pub fn find(uid: &String) -> Result<User, MdbError> {
|
||||
let env = utils::get_release_env();
|
||||
let s = db::DatabaseEnvironment::open(&env.value())?;
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &uid.as_bytes().to_vec())?;
|
||||
if r.is_empty() {
|
||||
error!("user not found");
|
||||
return Default::default();
|
||||
return Err(MdbError::NotFound);
|
||||
}
|
||||
User::from_db(String::from(uid), r)
|
||||
}
|
||||
|
||||
/// Modify user - not implemented
|
||||
fn _modify(u: Json<User>) -> User {
|
||||
info!("modify user: {}", u.uid);
|
||||
let f_cust: User = find(&u.uid);
|
||||
if f_cust.uid == utils::empty_string() {
|
||||
error!("user not found");
|
||||
return Default::default();
|
||||
}
|
||||
let u_user = User::update(f_cust, String::from(&u.name));
|
||||
let s = db::Interface::open();
|
||||
db::Interface::delete(&s.env, &s.handle, &u_user.uid);
|
||||
db::Interface::write(&s.env, &s.handle, &u_user.uid, &User::to_db(&u_user));
|
||||
todo!()
|
||||
let user: User = bincode::deserialize(&r[..]).unwrap_or_default();
|
||||
Ok(user)
|
||||
}
|
||||
|
||||
// Tests
|
||||
|
@ -59,42 +47,34 @@ fn _modify(u: Json<User>) -> User {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use kn0sys_lmdb_rs::MdbError;
|
||||
|
||||
use super::*;
|
||||
|
||||
async fn cleanup(k: &String) {
|
||||
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
|
||||
let s = db::Interface::async_open().await;
|
||||
db::Interface::async_delete(&s.env, &s.handle, k).await;
|
||||
fn cleanup(k: &String) -> Result<(), MdbError> {
|
||||
let s = db::DatabaseEnvironment::open("test")?;
|
||||
db::DatabaseEnvironment::delete(&s.env, &s.handle?, k.as_bytes());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn create_test() {
|
||||
// run and async cleanup so the test doesn't fail when deleting test data
|
||||
use tokio::runtime::Runtime;
|
||||
let rt = Runtime::new().expect("Unable to create Runtime for test");
|
||||
let _enter = rt.enter();
|
||||
let address: String = String::from(
|
||||
"73a4nWuvkYoYoksGurDjKZQcZkmaxLaKbbeiKzHnMmqKivrCzq5Q2JtJG1UZNZFqLPbQ3MiXCk2Q5bdwdUNSr7X9QrPubkn"
|
||||
);
|
||||
let test_user = create(&address);
|
||||
tokio::spawn(async move {
|
||||
let s = db::Interface::async_open().await;
|
||||
let r = db::Interface::async_read(&s.env, &s.handle, &test_user.uid).await;
|
||||
let s = db::DatabaseEnvironment::open("test")?;
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle?, &test_user.uid);
|
||||
let id = String::from(&test_user.uid);
|
||||
let cleanup_id = String::from(&test_user.uid);
|
||||
let expected_user = User::from_db(id, r);
|
||||
assert_eq!(test_user.xmr_address, expected_user.xmr_address);
|
||||
cleanup(&cleanup_id).await;
|
||||
});
|
||||
Runtime::shutdown_background(rt);
|
||||
cleanup(&cleanup_id);
|
||||
}
|
||||
|
||||
#[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 address: String = String::from(
|
||||
"73a4nWuvkYoYoksGurDjKZQcZkmaxLaKbbeiKzHnMmqKivrCzq5Q2JtJG1UZNZFqLPbQ3MiXCk2Q5bdwdUNSr7X9QrPubkn"
|
||||
);
|
||||
|
@ -103,13 +83,10 @@ mod tests {
|
|||
xmr_address: address,
|
||||
..Default::default()
|
||||
};
|
||||
tokio::spawn(async move {
|
||||
let s = db::Interface::async_open().await;
|
||||
db::Interface::async_write(&s.env, &s.handle, k, &User::to_db(&expected_user)).await;
|
||||
let s = db::DatabaseEnvironment::open("test")?;
|
||||
db::DatabaseEnvironment::write_chunks(&s.env, &s.handle?, k, &User::to_db(&expected_user));
|
||||
let actual_user: User = find(&String::from(k));
|
||||
assert_eq!(expected_user.xmr_address, actual_user.xmr_address);
|
||||
cleanup(&String::from(k)).await;
|
||||
});
|
||||
Runtime::shutdown_background(rt);
|
||||
cleanup(&String::from(k));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ use crate::{
|
|||
utils,
|
||||
};
|
||||
use clap::Parser;
|
||||
use kn0sys_lmdb_rs::MdbError;
|
||||
use log::{
|
||||
debug,
|
||||
error,
|
||||
|
@ -49,13 +50,13 @@ pub struct ContactStatus {
|
|||
impl Default for ContactStatus {
|
||||
fn default() -> Self {
|
||||
ContactStatus {
|
||||
exp: utils::empty_string(),
|
||||
h_exp: utils::empty_string(),
|
||||
i2p: utils::empty_string(),
|
||||
exp: String::new(),
|
||||
h_exp: String::new(),
|
||||
i2p: String::new(),
|
||||
is_vendor: false,
|
||||
jwp: utils::empty_string(),
|
||||
jwp: String::new(),
|
||||
nick: String::from("anon"),
|
||||
txp: utils::empty_string(),
|
||||
txp: String::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -307,7 +308,7 @@ pub fn message_to_json(m: &models::Message) -> Json<models::Message> {
|
|||
let r_message: models::Message = models::Message {
|
||||
body: String::from(&m.body),
|
||||
mid: String::from(&m.mid),
|
||||
uid: utils::empty_string(),
|
||||
uid: String::new(),
|
||||
created: m.created,
|
||||
from: String::from(&m.from),
|
||||
to: String::from(&m.to),
|
||||
|
@ -350,11 +351,6 @@ pub fn dispute_to_json(d: &models::Dispute) -> Json<models::Dispute> {
|
|||
Json(dispute)
|
||||
}
|
||||
|
||||
/// Instead of putting `String::from("")`
|
||||
pub fn empty_string() -> String {
|
||||
String::from("")
|
||||
}
|
||||
|
||||
// DoS prevention
|
||||
pub const fn string_limit() -> usize {
|
||||
512
|
||||
|
@ -411,35 +407,40 @@ async fn gen_app_wallet(password: &String) {
|
|||
}
|
||||
|
||||
/// Secret keys for signing internal/external auth tokens
|
||||
fn gen_signing_keys() {
|
||||
fn gen_signing_keys() -> Result<(), MdbError> {
|
||||
info!("generating signing keys");
|
||||
let jwp = get_jwp_secret_key();
|
||||
let jwt = get_jwt_secret_key();
|
||||
// send to db
|
||||
let s = db::Interface::open();
|
||||
if jwp == utils::empty_string() {
|
||||
let rnd_jwp = generate_rnd();
|
||||
db::Interface::write(&s.env, &s.handle, crate::NEVEKO_JWP_SECRET_KEY, &rnd_jwp);
|
||||
let env = utils::get_release_env();
|
||||
if jwp.is_empty() {
|
||||
let mut data = [0u8; 32];
|
||||
rand::thread_rng().fill_bytes(&mut data);
|
||||
let s = db::DatabaseEnvironment::open(&env.value())?;
|
||||
db::write_chunks(&s.env, &s.handle?, crate::NEVEKO_JWP_SECRET_KEY.as_bytes(), &data);
|
||||
}
|
||||
if jwt == utils::empty_string() {
|
||||
let rnd_jwt = generate_rnd();
|
||||
db::Interface::write(&s.env, &s.handle, crate::NEVEKO_JWT_SECRET_KEY, &rnd_jwt);
|
||||
if jwt.is_empty() {
|
||||
let mut data = [0u8; 32];
|
||||
rand::thread_rng().fill_bytes(&mut data);
|
||||
let s = db::DatabaseEnvironment::open(&env.value())?;
|
||||
db::write_chunks(&s.env, &s.handle?, crate::NEVEKO_JWT_SECRET_KEY.as_bytes(), &data);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// TODO(c2m): add a button to gui to call this
|
||||
///
|
||||
/// dont' forget to generate new keys as well
|
||||
pub fn revoke_signing_keys() {
|
||||
let s = db::Interface::open();
|
||||
db::Interface::delete(&s.env, &s.handle, crate::NEVEKO_JWT_SECRET_KEY);
|
||||
db::Interface::delete(&s.env, &s.handle, crate::NEVEKO_JWP_SECRET_KEY);
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
db::DatabaseEnvironment::delete(&s.env, &s.handle, crate::NEVEKO_JWT_SECRET_KEY);
|
||||
db::DatabaseEnvironment::delete(&s.env, &s.handle, crate::NEVEKO_JWP_SECRET_KEY);
|
||||
}
|
||||
|
||||
pub fn get_jwt_secret_key() -> String {
|
||||
let s = db::Interface::open();
|
||||
let r = db::Interface::read(&s.env, &s.handle, crate::NEVEKO_JWT_SECRET_KEY);
|
||||
if r == utils::empty_string() {
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, crate::NEVEKO_JWT_SECRET_KEY);
|
||||
if r.is_empty() {
|
||||
error!("JWT key not found");
|
||||
return Default::default();
|
||||
}
|
||||
|
@ -447,9 +448,9 @@ pub fn get_jwt_secret_key() -> String {
|
|||
}
|
||||
|
||||
pub fn get_jwp_secret_key() -> String {
|
||||
let s = db::Interface::open();
|
||||
let r = db::Interface::read(&s.env, &s.handle, crate::NEVEKO_JWP_SECRET_KEY);
|
||||
if r == utils::empty_string() {
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, crate::NEVEKO_JWP_SECRET_KEY);
|
||||
if r.is_empty() {
|
||||
error!("JWP key not found");
|
||||
return Default::default();
|
||||
}
|
||||
|
@ -458,9 +459,9 @@ pub fn get_jwp_secret_key() -> String {
|
|||
|
||||
/// Returns the hex encoded neveko message public key from LMDB
|
||||
pub fn get_nmpk() -> String {
|
||||
let s = db::Interface::open();
|
||||
let r = db::Interface::read(&s.env, &s.handle, crate::NEVEKO_NMPK);
|
||||
if r == utils::empty_string() {
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, crate::NEVEKO_NMPK);
|
||||
if r.is_empty() {
|
||||
error!("neveko message public key not found");
|
||||
return Default::default();
|
||||
}
|
||||
|
@ -471,10 +472,10 @@ async fn generate_nmpk() {
|
|||
info!("generating neveko message public key");
|
||||
let nmpk: String = get_nmpk();
|
||||
// send to db
|
||||
let s = db::Interface::open();
|
||||
if nmpk == utils::empty_string() {
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
if nmpk.is_empty() {
|
||||
let nmk: neveko25519::NevekoMessageKeys = neveko25519::generate_neveko_message_keys().await;
|
||||
db::Interface::write(&s.env, &s.handle, crate::NEVEKO_NMPK, &nmk.hex_nmpk);
|
||||
db::DatabaseEnvironment::write(&s.env, &s.handle, crate::NEVEKO_NMPK, &nmk.hex_nmpk);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -573,106 +574,15 @@ pub fn restart_dispute_auto_settle() {
|
|||
/// Called on app startup if `--clear-fts` flag is passed.
|
||||
fn clear_fts() {
|
||||
info!("clear fts");
|
||||
let s = db::Interface::open();
|
||||
db::Interface::delete(&s.env, &s.handle, crate::FTS_DB_KEY);
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
db::DatabaseEnvironment::delete(&s.env, &s.handle, crate::FTS_DB_KEY);
|
||||
}
|
||||
|
||||
/// Called on app startup if `--clear-dispute` flag is passed.
|
||||
fn clear_disputes() {
|
||||
info!("clear_disputes");
|
||||
let s = db::Interface::open();
|
||||
db::Interface::delete(&s.env, &s.handle, crate::DISPUTE_LIST_DB_KEY);
|
||||
}
|
||||
|
||||
/// TODO(?): get rid of this after implementing monero bindings
|
||||
///
|
||||
/// Handle the request from user to additional software
|
||||
///
|
||||
/// from gui startup. Power users will most like install
|
||||
///
|
||||
/// software on their own. Note that software pull is over
|
||||
///
|
||||
/// clearnet. TODO(c2m): remove this after monero and i2pd
|
||||
///
|
||||
/// are completed.
|
||||
pub async fn install_software(installations: Installations) -> bool {
|
||||
let mut valid_i2p_zero_hash = true;
|
||||
let mut valid_xmr_hash = true;
|
||||
if installations.i2p_zero {
|
||||
info!("installing i2p-zero");
|
||||
let i2p_version = crate::I2P_ZERO_RELEASE_VERSION;
|
||||
let i2p_zero_zip = format!("i2p-zero-linux.{}.zip", i2p_version);
|
||||
let link = format!(
|
||||
"https://github.com/creating2morrow/i2p-zero/releases/download/{}-neveko/{}",
|
||||
i2p_version, i2p_zero_zip
|
||||
);
|
||||
let curl = std::process::Command::new("curl")
|
||||
.args(["-LO#", &link])
|
||||
.status();
|
||||
match curl {
|
||||
Ok(curl_output) => {
|
||||
debug!("{:?}", curl_output);
|
||||
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
|
||||
let unzip_output = std::process::Command::new("unzip")
|
||||
.arg(&i2p_zero_zip)
|
||||
.spawn()
|
||||
.expect("i2p unzip failed");
|
||||
debug!("{:?}", unzip_output.stdout);
|
||||
}
|
||||
_ => error!("i2p-zero download failed"),
|
||||
}
|
||||
valid_i2p_zero_hash = validate_installation_hash(ExternalSoftware::I2PZero, &i2p_zero_zip);
|
||||
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
|
||||
}
|
||||
if installations.xmr {
|
||||
info!("installing monero");
|
||||
let link = format!(
|
||||
"https://downloads.getmonero.org/cli/{}",
|
||||
crate::MONERO_RELEASE_VERSION
|
||||
);
|
||||
let curl = std::process::Command::new("curl")
|
||||
.args(["-O#", &link])
|
||||
.status();
|
||||
match curl {
|
||||
Ok(curl_output) => {
|
||||
debug!("{:?}", curl_output);
|
||||
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
|
||||
let tar_output = std::process::Command::new("tar")
|
||||
.args(["-xvf", crate::MONERO_RELEASE_VERSION])
|
||||
.spawn()
|
||||
.expect("monero tar extraction failed");
|
||||
debug!("{:?}", tar_output.stdout);
|
||||
}
|
||||
_ => error!("monero download failed"),
|
||||
}
|
||||
valid_xmr_hash = validate_installation_hash(
|
||||
ExternalSoftware::XMR,
|
||||
&String::from(crate::MONERO_RELEASE_VERSION),
|
||||
);
|
||||
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
|
||||
}
|
||||
valid_i2p_zero_hash && valid_xmr_hash
|
||||
}
|
||||
|
||||
/// Linux specific hash validation using the command `sha256sum`
|
||||
fn validate_installation_hash(sw: ExternalSoftware, filename: &String) -> bool {
|
||||
debug!("validating hash");
|
||||
let expected_hash = if sw == ExternalSoftware::I2PZero {
|
||||
String::from(crate::I2P_ZERO_RELEASH_HASH)
|
||||
} else {
|
||||
String::from(crate::MONERO_RELEASE_HASH)
|
||||
};
|
||||
let sha_output = std::process::Command::new("sha256sum")
|
||||
.arg(filename)
|
||||
.output()
|
||||
.expect("hash validation failed");
|
||||
let str_sha = String::from_utf8(sha_output.stdout).unwrap();
|
||||
let split1 = str_sha.split(" ");
|
||||
let mut v: Vec<String> = split1.map(String::from).collect();
|
||||
let actual_hash = v.remove(0);
|
||||
debug!("actual hash: {}", actual_hash);
|
||||
debug!("expected hash: {}", expected_hash);
|
||||
actual_hash == expected_hash
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
db::DatabaseEnvironment::delete(&s.env, &s.handle, crate::DISPUTE_LIST_DB_KEY);
|
||||
}
|
||||
|
||||
/// ### The highly ineffecient fee estimator.
|
||||
|
@ -700,7 +610,7 @@ pub async fn estimate_fee() -> u128 {
|
|||
let mut count: u64 = 1;
|
||||
let mut v_fee: Vec<u128> = Vec::new();
|
||||
let mut r_height: reqres::XmrDaemonGetHeightResponse = Default::default();
|
||||
let remote_var = std::env::var(crate::GUI_REMOTE_NODE).unwrap_or(utils::empty_string());
|
||||
let remote_var = std::env::var(crate::GUI_REMOTE_NODE).unwrap_or(String::new());
|
||||
let remote_set = remote_var == *crate::GUI_SET_REMOTE_NODE;
|
||||
if remote_set {
|
||||
let p_height = monero::p_get_height().await;
|
||||
|
@ -780,11 +690,11 @@ pub async fn can_transfer(invoice: u128) -> bool {
|
|||
/// Gui toggle for vendor mode
|
||||
pub fn toggle_vendor_enabled() -> bool {
|
||||
// TODO(c2m): Dont toggle vendors with orders status != Delivered
|
||||
let s = db::Interface::open();
|
||||
let r = db::Interface::read(&s.env, &s.handle, contact::NEVEKO_VENDOR_ENABLED);
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, contact::NEVEKO_VENDOR_ENABLED);
|
||||
if r != contact::NEVEKO_VENDOR_MODE_ON {
|
||||
info!("neveko vendor mode enabled");
|
||||
db::Interface::write(
|
||||
db::DatabaseEnvironment::write(
|
||||
&s.env,
|
||||
&s.handle,
|
||||
contact::NEVEKO_VENDOR_ENABLED,
|
||||
|
@ -793,7 +703,7 @@ pub fn toggle_vendor_enabled() -> bool {
|
|||
true
|
||||
} else {
|
||||
info!("neveko vendor mode disabled");
|
||||
db::Interface::write(
|
||||
db::DatabaseEnvironment::write(
|
||||
&s.env,
|
||||
&s.handle,
|
||||
contact::NEVEKO_VENDOR_ENABLED,
|
||||
|
@ -804,21 +714,21 @@ pub fn toggle_vendor_enabled() -> bool {
|
|||
}
|
||||
|
||||
pub fn search_gui_db(f: String, data: String) -> String {
|
||||
let s = db::Interface::open();
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
let k = format!("{}-{}", f, data);
|
||||
db::Interface::read(&s.env, &s.handle, &k)
|
||||
db::DatabaseEnvironment::read(&s.env, &s.handle, &k)
|
||||
}
|
||||
|
||||
pub fn write_gui_db(f: String, key: String, data: String) {
|
||||
let s = db::Interface::open();
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
let k = format!("{}-{}", f, key);
|
||||
db::Interface::write(&s.env, &s.handle, &k, &data);
|
||||
db::DatabaseEnvironment::write(&s.env, &s.handle, &k, &data);
|
||||
}
|
||||
|
||||
pub fn clear_gui_db(f: String, key: String) {
|
||||
let s = db::Interface::open();
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
let k = format!("{}-{}", f, key);
|
||||
db::Interface::delete(&s.env, &s.handle, &k);
|
||||
db::DatabaseEnvironment::delete(&s.env, &s.handle, &k);
|
||||
}
|
||||
|
||||
// Tests
|
||||
|
|
|
@ -18,8 +18,8 @@ struct Compose {
|
|||
impl Default for Compose {
|
||||
fn default() -> Self {
|
||||
Compose {
|
||||
message: utils::empty_string(),
|
||||
to: utils::empty_string(),
|
||||
message: String::new(),
|
||||
to: String::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ impl Default for AddressBookApp {
|
|||
let (payment_tx, payment_rx) = std::sync::mpsc::channel();
|
||||
let (send_message_tx, send_message_rx) = std::sync::mpsc::channel();
|
||||
AddressBookApp {
|
||||
add_nick: utils::empty_string(),
|
||||
add_nick: String::new(),
|
||||
approve_contact: false,
|
||||
approve_payment: false,
|
||||
added: false,
|
||||
|
@ -94,7 +94,7 @@ impl Default for AddressBookApp {
|
|||
can_transfer_rx,
|
||||
can_transfer_tx,
|
||||
compose: Default::default(),
|
||||
contact: utils::empty_string(),
|
||||
contact: String::new(),
|
||||
contacts: Vec::new(),
|
||||
contacts_init: false,
|
||||
contact_add_tx,
|
||||
|
@ -103,7 +103,7 @@ impl Default for AddressBookApp {
|
|||
contact_info_rx,
|
||||
contact_timeout_tx,
|
||||
contact_timeout_rx,
|
||||
find_contact: utils::empty_string(),
|
||||
find_contact: String::new(),
|
||||
invoice_tx,
|
||||
invoice_rx,
|
||||
is_adding: false,
|
||||
|
@ -134,7 +134,7 @@ impl eframe::App for AddressBookApp {
|
|||
//-----------------------------------------------------------------------------------
|
||||
if let Ok(contact_info) = self.contact_info_rx.try_recv() {
|
||||
self.s_contact = contact_info;
|
||||
if self.s_contact.xmr_address != utils::empty_string() && !self.showing_status {
|
||||
if !self.s_contact.xmr_address.is_empty() && !self.showing_status {
|
||||
self.approve_contact = true;
|
||||
}
|
||||
if self.showing_status {
|
||||
|
@ -144,7 +144,7 @@ impl eframe::App for AddressBookApp {
|
|||
|
||||
if let Ok(added_contact) = self.contact_add_rx.try_recv() {
|
||||
self.s_added_contact = added_contact;
|
||||
if self.s_added_contact.cid != utils::empty_string() {
|
||||
if !self.s_added_contact.cid.is_empty() {
|
||||
self.added = true;
|
||||
self.is_loading = false;
|
||||
}
|
||||
|
@ -156,7 +156,7 @@ impl eframe::App for AddressBookApp {
|
|||
self.is_loading = false;
|
||||
self.is_adding = false;
|
||||
self.approve_contact = false;
|
||||
self.contact = utils::empty_string();
|
||||
self.contact = String::new();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -186,7 +186,7 @@ impl eframe::App for AddressBookApp {
|
|||
if self.is_message_sent {
|
||||
self.is_loading = false;
|
||||
self.is_composing = false;
|
||||
self.compose.message = utils::empty_string();
|
||||
self.compose.message = String::new();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -222,7 +222,7 @@ impl eframe::App for AddressBookApp {
|
|||
});
|
||||
if !self.is_loading {
|
||||
self.compose.to = self.status.i2p.clone();
|
||||
if self.status.jwp != utils::empty_string() {
|
||||
if !self.status.jwp.is_empty() {
|
||||
if ui.button("Send").clicked() {
|
||||
self.is_loading = true;
|
||||
send_message_req(
|
||||
|
@ -243,7 +243,7 @@ impl eframe::App for AddressBookApp {
|
|||
// Payment approval window
|
||||
//-----------------------------------------------------------------------------------
|
||||
let mut is_approving_payment =
|
||||
self.approve_payment && self.s_invoice.address != utils::empty_string();
|
||||
self.approve_payment && !self.s_invoice.address.is_empty();
|
||||
let address = self.s_invoice.address.clone();
|
||||
let amount = self.s_invoice.pay_threshold;
|
||||
let expire = self.s_invoice.conf_threshold;
|
||||
|
@ -265,7 +265,7 @@ impl eframe::App for AddressBookApp {
|
|||
ui.label(format!("pay to: {}", address));
|
||||
ui.label(format!("amount: {} piconero(s)", amount));
|
||||
ui.label(format!("expiration: {} blocks", expire));
|
||||
let show_approve = self.s_invoice.address != utils::empty_string()
|
||||
let show_approve = !self.s_invoice.address.is_empty()
|
||||
&& self.can_transfer
|
||||
&& !self.is_estimating_fee;
|
||||
if !self.is_loading {
|
||||
|
@ -316,7 +316,7 @@ impl eframe::App for AddressBookApp {
|
|||
ui.add(egui::Spinner::new());
|
||||
ui.label(spinner_text);
|
||||
}
|
||||
let status = if self.s_contact.xmr_address != utils::empty_string() {
|
||||
let status = if !self.s_contact.xmr_address.is_empty() {
|
||||
"online"
|
||||
} else {
|
||||
"offline"
|
||||
|
@ -326,10 +326,10 @@ impl eframe::App for AddressBookApp {
|
|||
ui.label(format!("tx proof: {}", self.status.txp));
|
||||
ui.label(format!("jwp: {}", self.status.jwp));
|
||||
ui.label(format!("expiration: {}", self.status.h_exp));
|
||||
if self.status.jwp == utils::empty_string()
|
||||
if self.status.jwp.is_empty()
|
||||
&& !self.is_pinging
|
||||
&& status == "online"
|
||||
&& self.status.txp == utils::empty_string()
|
||||
&& self.status.txp.is_empty()
|
||||
{
|
||||
if ui.button("Create JWP").clicked() {
|
||||
self.s_invoice = Default::default();
|
||||
|
@ -343,9 +343,9 @@ impl eframe::App for AddressBookApp {
|
|||
self.is_approving_jwp = true;
|
||||
}
|
||||
}
|
||||
let failed_to_prove = self.status.txp != utils::empty_string()
|
||||
&& self.status.jwp == utils::empty_string();
|
||||
if self.status.jwp != utils::empty_string() || failed_to_prove {
|
||||
let failed_to_prove = !self.status.txp.is_empty()
|
||||
&& 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());
|
||||
|
@ -353,8 +353,8 @@ impl eframe::App for AddressBookApp {
|
|||
self.showing_status = false;
|
||||
}
|
||||
}
|
||||
if self.status.txp != utils::empty_string()
|
||||
&& self.status.jwp == utils::empty_string()
|
||||
if !self.status.txp.is_empty()
|
||||
&& self.status.jwp.is_empty()
|
||||
&& status == "online"
|
||||
{
|
||||
if ui.button("Prove Retry").clicked() {
|
||||
|
@ -376,7 +376,7 @@ impl eframe::App for AddressBookApp {
|
|||
});
|
||||
if ui.button("Change nick").clicked() {
|
||||
change_nick_req(self.status.i2p.clone(), self.add_nick.clone());
|
||||
self.add_nick = utils::empty_string();
|
||||
self.add_nick = String::new();
|
||||
}
|
||||
if ui.button("Exit").clicked() {
|
||||
self.showing_status = false;
|
||||
|
@ -419,7 +419,7 @@ impl eframe::App for AddressBookApp {
|
|||
ui.label(format!("i2p address: {}", self.s_added_contact.i2p_address));
|
||||
if ui.button("Exit").clicked() {
|
||||
self.added = false;
|
||||
self.contact = utils::empty_string();
|
||||
self.contact = String::new();
|
||||
self.is_adding = false;
|
||||
self.approve_contact = false;
|
||||
self.contacts = contact::find_all();
|
||||
|
@ -541,7 +541,7 @@ impl eframe::App for AddressBookApp {
|
|||
String::from(crate::GUI_NICK_DB_KEY),
|
||||
String::from(&c.i2p_address),
|
||||
);
|
||||
let nick = if nick_db == utils::empty_string() {
|
||||
let nick = if nick_db.is_empty() {
|
||||
String::from("anon")
|
||||
} else {
|
||||
nick_db
|
||||
|
@ -587,7 +587,7 @@ impl eframe::App for AddressBookApp {
|
|||
Err(_e) => 0,
|
||||
};
|
||||
if now < expire
|
||||
&& self.status.jwp != utils::empty_string()
|
||||
&& !self.status.jwp.is_empty()
|
||||
&& c.i2p_address == self.status.i2p
|
||||
{
|
||||
if ui.button("Compose").clicked() {
|
||||
|
@ -683,14 +683,14 @@ fn send_payment_req(
|
|||
subaddress: ptxp_address,
|
||||
confirmations: 0,
|
||||
hash: ptxp_hash,
|
||||
message: utils::empty_string(),
|
||||
signature: utils::empty_string(),
|
||||
message: String::new(),
|
||||
signature: String::new(),
|
||||
};
|
||||
log::debug!("creating transaction proof for: {}", &ptxp.hash);
|
||||
// if we made it this far we can now request a JWP from our friend
|
||||
// wait a bit for the tx to propogate, i2p takes longer
|
||||
let wait = if std::env::var(neveko_core::GUI_REMOTE_NODE)
|
||||
.unwrap_or(utils::empty_string())
|
||||
.unwrap_or(String::new())
|
||||
== String::from(neveko_core::GUI_SET_REMOTE_NODE)
|
||||
{
|
||||
crate::I2P_PROPAGATION_TIME_IN_SECS_EST
|
||||
|
@ -705,7 +705,7 @@ fn send_payment_req(
|
|||
subaddress: ftxp_address,
|
||||
confirmations: 0,
|
||||
hash: ftxp_hash,
|
||||
message: utils::empty_string(),
|
||||
message: String::new(),
|
||||
signature: get_txp.result.signature,
|
||||
};
|
||||
utils::write_gui_db(
|
||||
|
@ -765,7 +765,7 @@ fn send_payment_req(
|
|||
subaddress,
|
||||
confirmations: 0,
|
||||
hash: String::from(&hash),
|
||||
message: utils::empty_string(),
|
||||
message: String::new(),
|
||||
signature,
|
||||
};
|
||||
log::debug!(
|
||||
|
@ -795,8 +795,8 @@ fn send_message_req(tx: Sender<bool>, ctx: egui::Context, body: String, to: Stri
|
|||
let m: models::Message = models::Message {
|
||||
body: body,
|
||||
to,
|
||||
mid: utils::empty_string(),
|
||||
uid: utils::empty_string(),
|
||||
mid: String::new(),
|
||||
uid: String::new(),
|
||||
created: 0,
|
||||
from: i2p::get_destination(None),
|
||||
};
|
||||
|
@ -804,7 +804,7 @@ 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 != utils::empty_string() {
|
||||
if !result.mid.is_empty() {
|
||||
log::info!("sent message: {}", result.mid);
|
||||
let _ = tx.send(true);
|
||||
ctx.request_repaint();
|
||||
|
|
|
@ -24,10 +24,6 @@ pub struct HomeApp {
|
|||
connections: utils::Connections,
|
||||
core_timeout_tx: Sender<bool>,
|
||||
core_timeout_rx: Receiver<bool>,
|
||||
has_install_failed: bool,
|
||||
installations: utils::Installations,
|
||||
installation_tx: Sender<bool>,
|
||||
installation_rx: Receiver<bool>,
|
||||
is_core_running: bool,
|
||||
is_editing_connections: bool,
|
||||
is_init: bool,
|
||||
|
@ -111,10 +107,6 @@ impl Default for HomeApp {
|
|||
connections,
|
||||
core_timeout_rx,
|
||||
core_timeout_tx,
|
||||
has_install_failed,
|
||||
installations,
|
||||
installation_rx,
|
||||
installation_tx,
|
||||
is_core_running,
|
||||
is_editing_connections,
|
||||
is_init,
|
||||
|
@ -208,7 +200,7 @@ impl eframe::App for HomeApp {
|
|||
.vscroll(true)
|
||||
.show(ctx, |ui| {
|
||||
let mut i2p_address = i2p::get_destination(None);
|
||||
if !self.is_qr_set && i2p_address != utils::empty_string() {
|
||||
if !self.is_qr_set && !i2p_address.is_empty() {
|
||||
let code = QrCode::new(&i2p_address).unwrap();
|
||||
let image = code.render::<Luma<u8>>().build();
|
||||
let file_path = format!(
|
||||
|
@ -232,22 +224,6 @@ impl eframe::App for HomeApp {
|
|||
}
|
||||
});
|
||||
|
||||
// Installation Error window
|
||||
//-----------------------------------------------------------------------------------
|
||||
let mut has_install_failed = self.has_install_failed;
|
||||
egui::Window::new("error")
|
||||
.open(&mut has_install_failed)
|
||||
.title_bar(false)
|
||||
.vscroll(false)
|
||||
.show(&ctx, |ui| {
|
||||
ui.heading("Installation Failure");
|
||||
if ui.button("Exit").clicked() {
|
||||
self.has_install_failed = false;
|
||||
self.is_installing = false;
|
||||
self.is_loading = false;
|
||||
}
|
||||
});
|
||||
|
||||
// Connection Manager window
|
||||
//-----------------------------------------------------------------------------------
|
||||
let mut is_editing_connections = self.is_editing_connections;
|
||||
|
@ -343,42 +319,6 @@ impl eframe::App for HomeApp {
|
|||
}
|
||||
});
|
||||
|
||||
// Installation Manager window
|
||||
//-----------------------------------------------------------------------------------
|
||||
let mut is_installing = self.is_installing;
|
||||
egui::Window::new("installation")
|
||||
.open(&mut is_installing)
|
||||
.title_bar(false)
|
||||
.vscroll(true)
|
||||
.show(&ctx, |ui| {
|
||||
ui.heading("Installation Manager");
|
||||
let mut wants_i2p_zero = self.installations.i2p_zero;
|
||||
let mut wants_xmr = self.installations.xmr;
|
||||
if ui.checkbox(&mut wants_i2p_zero, "i2p-zero").changed() {
|
||||
self.installations.i2p_zero = !self.installations.i2p_zero;
|
||||
}
|
||||
if ui.checkbox(&mut wants_xmr, "xmr").changed() {
|
||||
self.installations.xmr = !self.installations.xmr;
|
||||
}
|
||||
let install = &self.installations;
|
||||
if install.i2p_zero || install.xmr {
|
||||
if !self.is_loading {
|
||||
if ui.button("Install").clicked() {
|
||||
self.is_loading = true;
|
||||
install_software_req(
|
||||
self.installation_tx.clone(),
|
||||
ctx.clone(),
|
||||
&self.installations,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ui.button("Exit").clicked() {
|
||||
self.is_installing = false;
|
||||
self.is_loading = false;
|
||||
}
|
||||
});
|
||||
|
||||
//----------------------------------------------------------------------------------------------
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
if !self.is_updated {
|
||||
|
@ -561,19 +501,3 @@ fn start_core_timeout(tx: Sender<bool>, ctx: egui::Context) {
|
|||
ctx.request_repaint();
|
||||
});
|
||||
}
|
||||
|
||||
fn install_software_req(
|
||||
tx: Sender<bool>,
|
||||
ctx: egui::Context,
|
||||
installations: &utils::Installations,
|
||||
) {
|
||||
let req_install: utils::Installations = utils::Installations {
|
||||
i2p_zero: installations.i2p_zero,
|
||||
xmr: installations.xmr,
|
||||
};
|
||||
tokio::spawn(async move {
|
||||
let did_install = utils::install_software(req_install).await;
|
||||
let _ = tx.send(did_install);
|
||||
ctx.request_repaint();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ struct LockScreen {
|
|||
impl Default for LockScreen {
|
||||
fn default() -> Self {
|
||||
LockScreen {
|
||||
credential: utils::empty_string(),
|
||||
credential: String::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -62,8 +62,8 @@ impl eframe::App for LockScreenApp {
|
|||
self.lock_screen.credential.clone(),
|
||||
);
|
||||
// Get the credential hash from lmdb
|
||||
let s = db::Interface::open();
|
||||
let r = db::Interface::read(&s.env, &s.handle, CREDENTIAL_KEY);
|
||||
let s = db::DatabaseEnvironment::open(&utils::get_release_env().value()).unwrap();
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, CREDENTIAL_KEY);
|
||||
// hash the text entered and compare
|
||||
let mut hasher = Sha512::new();
|
||||
hasher.update(self.lock_screen.credential.clone());
|
||||
|
|
|
@ -23,7 +23,7 @@ impl Default for MailBoxApp {
|
|||
let (refresh_on_delete_tx, refresh_on_delete_rx) = std::sync::mpsc::channel();
|
||||
let (deciphered_tx, deciphered_rx) = std::sync::mpsc::channel();
|
||||
MailBoxApp {
|
||||
deciphered: utils::empty_string(),
|
||||
deciphered: String::new(),
|
||||
is_showing_decipher: false,
|
||||
messages: Vec::new(),
|
||||
message_init: false,
|
||||
|
@ -67,7 +67,7 @@ impl eframe::App for MailBoxApp {
|
|||
ui.label(format!("{}", self.deciphered));
|
||||
ui.label("\n");
|
||||
if ui.button("Exit").clicked() {
|
||||
self.deciphered = utils::empty_string();
|
||||
self.deciphered = String::new();
|
||||
self.is_showing_decipher = false;
|
||||
}
|
||||
});
|
||||
|
|
|
@ -39,15 +39,15 @@ impl Default for MultisigManagement {
|
|||
completed_prepare: false,
|
||||
completed_shipping_request: false,
|
||||
completed_make: false,
|
||||
exchange_multisig_keys: utils::empty_string(),
|
||||
export_info: utils::empty_string(),
|
||||
exchange_multisig_keys: String::new(),
|
||||
export_info: String::new(),
|
||||
has_adjudicator: false,
|
||||
make_info: utils::empty_string(),
|
||||
adjudicator: utils::empty_string(),
|
||||
prepare_info: utils::empty_string(),
|
||||
make_info: String::new(),
|
||||
adjudicator: String::new(),
|
||||
prepare_info: String::new(),
|
||||
query_adjudicator: false,
|
||||
signed_txset: utils::empty_string(),
|
||||
vendor: utils::empty_string(),
|
||||
signed_txset: String::new(),
|
||||
vendor: String::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -140,8 +140,8 @@ 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::Interface::open();
|
||||
let r = db::Interface::read(&s.env, &s.handle, contact::NEVEKO_VENDOR_ENABLED);
|
||||
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 (contact_info_tx, contact_info_rx) = std::sync::mpsc::channel();
|
||||
let (get_vendor_products_tx, get_vendor_products_rx) = std::sync::mpsc::channel();
|
||||
|
@ -164,10 +164,10 @@ impl Default for MarketApp {
|
|||
contact_timeout_rx,
|
||||
contact_timeout_tx,
|
||||
customer_orders: Vec::new(),
|
||||
cipher: utils::empty_string(),
|
||||
cipher: String::new(),
|
||||
ciphered_tx,
|
||||
ciphered_rx,
|
||||
find_vendor: utils::empty_string(),
|
||||
find_vendor: String::new(),
|
||||
get_vendor_products_rx,
|
||||
get_vendor_products_tx,
|
||||
get_vendor_product_rx,
|
||||
|
@ -195,7 +195,7 @@ impl Default for MarketApp {
|
|||
is_window_shopping: false,
|
||||
msig: Default::default(),
|
||||
m_order: Default::default(),
|
||||
order_xmr_address: utils::empty_string(),
|
||||
order_xmr_address: String::new(),
|
||||
order_xmr_address_rx,
|
||||
order_xmr_address_tx,
|
||||
order_qr: egui_extras::RetainedImage::from_image_bytes("qr.png", &contents).unwrap(),
|
||||
|
@ -206,8 +206,8 @@ impl Default for MarketApp {
|
|||
our_prepare_info_tx,
|
||||
new_order: Default::default(),
|
||||
new_order_price: 0,
|
||||
new_order_shipping_address: utils::empty_string(),
|
||||
new_order_quantity: utils::empty_string(),
|
||||
new_order_shipping_address: String::new(),
|
||||
new_order_quantity: String::new(),
|
||||
orders: Vec::new(),
|
||||
product_from_vendor: Default::default(),
|
||||
product_image: egui_extras::RetainedImage::from_image_bytes(
|
||||
|
@ -216,12 +216,12 @@ impl Default for MarketApp {
|
|||
)
|
||||
.unwrap(),
|
||||
products: Vec::new(),
|
||||
product_update_pid: utils::empty_string(),
|
||||
new_product_image: utils::empty_string(),
|
||||
new_product_name: utils::empty_string(),
|
||||
new_product_desc: utils::empty_string(),
|
||||
new_product_price: utils::empty_string(),
|
||||
new_product_qty: utils::empty_string(),
|
||||
product_update_pid: String::new(),
|
||||
new_product_image: String::new(),
|
||||
new_product_name: String::new(),
|
||||
new_product_desc: String::new(),
|
||||
new_product_price: String::new(),
|
||||
new_product_qty: String::new(),
|
||||
_refresh_on_delete_product_tx,
|
||||
_refresh_on_delete_product_rx,
|
||||
s_contact: Default::default(),
|
||||
|
@ -238,7 +238,7 @@ impl Default for MarketApp {
|
|||
submit_txset_tx,
|
||||
vendor_status: Default::default(),
|
||||
vendors: Vec::new(),
|
||||
upload_dinfo_str: utils::empty_string(),
|
||||
upload_dinfo_str: String::new(),
|
||||
upload_dinfo_rx,
|
||||
upload_dinfo_tx,
|
||||
}
|
||||
|
@ -252,7 +252,7 @@ impl eframe::App for MarketApp {
|
|||
|
||||
if let Ok(submit_order) = self.submit_order_rx.try_recv() {
|
||||
self.s_order = submit_order;
|
||||
if self.s_order.orid != utils::empty_string() {
|
||||
if !self.s_order.orid.is_empty() {
|
||||
self.is_ordering = false;
|
||||
self.is_loading = false;
|
||||
}
|
||||
|
@ -260,7 +260,7 @@ impl eframe::App for MarketApp {
|
|||
|
||||
if let Ok(contact_info) = self.contact_info_rx.try_recv() {
|
||||
self.s_contact = contact_info;
|
||||
if self.s_contact.xmr_address != utils::empty_string() {
|
||||
if !self.s_contact.xmr_address.is_empty() {
|
||||
self.is_pinging = false;
|
||||
self.vendor_status.is_vendor = self.s_contact.is_vendor;
|
||||
}
|
||||
|
@ -325,7 +325,7 @@ impl eframe::App for MarketApp {
|
|||
|
||||
if let Ok(a) = self.order_xmr_address_rx.try_recv() {
|
||||
self.order_xmr_address = a.result.address;
|
||||
if self.order_xmr_address != utils::empty_string() {
|
||||
if !self.order_xmr_address.is_empty() {
|
||||
self.is_showing_order_qr = true;
|
||||
}
|
||||
}
|
||||
|
@ -357,7 +357,7 @@ impl eframe::App for MarketApp {
|
|||
}
|
||||
|
||||
if let Ok(disputed) = self.dispute_request_rx.try_recv() {
|
||||
if disputed.tx_set != utils::empty_string() {
|
||||
if !disputed.tx_set.is_empty() {
|
||||
log::info!("dispute in progress");
|
||||
}
|
||||
self.is_loading = false;
|
||||
|
@ -391,7 +391,7 @@ impl eframe::App for MarketApp {
|
|||
ui.add(egui::Spinner::new());
|
||||
ui.label("pinging...");
|
||||
}
|
||||
let status = if self.s_contact.xmr_address != utils::empty_string() {
|
||||
let status = if !self.s_contact.xmr_address.is_empty() {
|
||||
"online"
|
||||
} else {
|
||||
"offline"
|
||||
|
@ -452,7 +452,7 @@ impl eframe::App for MarketApp {
|
|||
let adjudicator_db =
|
||||
utils::search_gui_db(String::from(&prefix), self.m_order.orid.clone());
|
||||
log::debug!("adjudicator db: {}", adjudicator_db);
|
||||
self.msig.has_adjudicator = adjudicator_db != utils::empty_string();
|
||||
self.msig.has_adjudicator = !adjudicator_db.is_empty();
|
||||
self.msig.adjudicator = adjudicator_db;
|
||||
self.msig.query_adjudicator = true;
|
||||
} else if self.msig.query_adjudicator && !self.msig.has_adjudicator {
|
||||
|
@ -473,7 +473,7 @@ impl eframe::App for MarketApp {
|
|||
if !self.msig.completed_prepare {
|
||||
if ui.button("Clear Mediator").clicked() {
|
||||
utils::clear_gui_db(prefix, self.m_order.orid.clone());
|
||||
self.msig.adjudicator = utils::empty_string();
|
||||
self.msig.adjudicator = String::new();
|
||||
self.msig.has_adjudicator = false;
|
||||
self.msig.query_adjudicator = false;
|
||||
}
|
||||
|
@ -695,7 +695,7 @@ impl eframe::App for MarketApp {
|
|||
String::from(crate::GUI_MSIG_EXPORT_DB_KEY),
|
||||
String::from(&self.m_order.orid.clone()),
|
||||
);
|
||||
if info != utils::empty_string() {
|
||||
if !info.is_empty() {
|
||||
self.msig.completed_export = true;
|
||||
}
|
||||
}
|
||||
|
@ -779,7 +779,7 @@ impl eframe::App for MarketApp {
|
|||
.title_bar(false)
|
||||
.vscroll(true)
|
||||
.show(ctx, |ui| {
|
||||
if !self.is_order_qr_set && self.order_xmr_address != utils::empty_string() {
|
||||
if !self.is_order_qr_set && !self.order_xmr_address.is_empty() {
|
||||
let code = QrCode::new(&self.order_xmr_address.clone()).unwrap();
|
||||
let image = code.render::<Luma<u8>>().build();
|
||||
let file_path = format!(
|
||||
|
@ -814,7 +814,7 @@ impl eframe::App for MarketApp {
|
|||
ui.label(format!("{}", self.cipher));
|
||||
ui.label("\n");
|
||||
if ui.button("Exit").clicked() {
|
||||
self.cipher = utils::empty_string();
|
||||
self.cipher = String::new();
|
||||
self.is_showing_deciphered_delivery_info = false;
|
||||
}
|
||||
});
|
||||
|
@ -1026,8 +1026,8 @@ impl eframe::App for MarketApp {
|
|||
);
|
||||
self.new_order = Default::default();
|
||||
self.new_order_price = 0;
|
||||
self.new_order_quantity = utils::empty_string();
|
||||
self.new_order_shipping_address = utils::empty_string();
|
||||
self.new_order_quantity = String::new();
|
||||
self.new_order_shipping_address = String::new();
|
||||
self.is_showing_products = false;
|
||||
}
|
||||
}
|
||||
|
@ -1057,8 +1057,8 @@ impl eframe::App for MarketApp {
|
|||
ui.text_edit_singleline(&mut self.upload_dinfo_str)
|
||||
.labelled_by(delivery_info.id);
|
||||
});
|
||||
if self.new_order.orid != utils::empty_string()
|
||||
&& self.upload_dinfo_str != utils::empty_string()
|
||||
if !self.new_order.orid.is_empty()
|
||||
&& !self.upload_dinfo_str.is_empty()
|
||||
{
|
||||
if ui.button("Trigger NASR").clicked() {
|
||||
// upload delivery info
|
||||
|
@ -1146,7 +1146,7 @@ impl eframe::App for MarketApp {
|
|||
String::from(crate::GUI_NICK_DB_KEY),
|
||||
String::from(&v.i2p_address),
|
||||
);
|
||||
let nick = if nick_db == utils::empty_string() {
|
||||
let nick = if nick_db.is_empty() {
|
||||
String::from("anon")
|
||||
} else {
|
||||
nick_db
|
||||
|
@ -1199,7 +1199,7 @@ impl eframe::App for MarketApp {
|
|||
Err(_e) => 0,
|
||||
};
|
||||
if now < expire
|
||||
&& self.vendor_status.jwp != utils::empty_string()
|
||||
&& !self.vendor_status.jwp.is_empty()
|
||||
&& v.i2p_address == self.vendor_status.i2p
|
||||
&& self.vendor_status.is_vendor
|
||||
{
|
||||
|
@ -1239,7 +1239,7 @@ impl eframe::App for MarketApp {
|
|||
ui.add(egui::Spinner::new());
|
||||
ui.label("pinging...");
|
||||
}
|
||||
let status = if self.s_contact.xmr_address != utils::empty_string() {
|
||||
let status = if !self.s_contact.xmr_address.is_empty() {
|
||||
"online"
|
||||
} else {
|
||||
"offline"
|
||||
|
@ -1495,20 +1495,20 @@ impl eframe::App for MarketApp {
|
|||
};
|
||||
let j_product = utils::product_to_json(&product);
|
||||
product::modify(j_product);
|
||||
self.new_product_desc = utils::empty_string();
|
||||
self.new_product_name = utils::empty_string();
|
||||
self.new_product_price = utils::empty_string();
|
||||
self.new_product_qty = utils::empty_string();
|
||||
self.new_product_image = utils::empty_string();
|
||||
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();
|
||||
}
|
||||
if ui.button("Exit").clicked() {
|
||||
self.new_product_desc = utils::empty_string();
|
||||
self.new_product_name = utils::empty_string();
|
||||
self.new_product_price = utils::empty_string();
|
||||
self.new_product_qty = utils::empty_string();
|
||||
self.new_product_image = utils::empty_string();
|
||||
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;
|
||||
}
|
||||
});
|
||||
|
@ -1688,7 +1688,7 @@ impl eframe::App for MarketApp {
|
|||
Err(_) => 0,
|
||||
};
|
||||
let product: models::Product = models::Product {
|
||||
pid: utils::empty_string(),
|
||||
pid: String::new(),
|
||||
description: self.new_product_desc.clone(),
|
||||
image,
|
||||
in_stock: qty > 0,
|
||||
|
@ -1698,11 +1698,11 @@ impl eframe::App for MarketApp {
|
|||
};
|
||||
let j_product = utils::product_to_json(&product);
|
||||
product::create(j_product);
|
||||
self.new_product_desc = utils::empty_string();
|
||||
self.new_product_name = utils::empty_string();
|
||||
self.new_product_price = utils::empty_string();
|
||||
self.new_product_qty = utils::empty_string();
|
||||
self.new_product_image = utils::empty_string();
|
||||
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();
|
||||
}
|
||||
ui.label("\n");
|
||||
if ui.button("View Products").clicked() {
|
||||
|
@ -1833,13 +1833,13 @@ fn send_prepare_info_req(
|
|||
);
|
||||
let v_jwp: String =
|
||||
utils::search_gui_db(String::from(crate::GUI_JWP_DB_KEY), String::from(&vendor));
|
||||
let wallet_password = utils::empty_string();
|
||||
let wallet_password = String::new();
|
||||
monero::create_wallet(&w_orid, &wallet_password).await;
|
||||
let m_wallet = monero::open_wallet(&w_orid, &wallet_password).await;
|
||||
if !m_wallet {
|
||||
log::error!("failed to open wallet");
|
||||
monero::close_wallet(&w_orid, &wallet_password).await;
|
||||
let _ = tx.send(utils::empty_string());
|
||||
let _ = tx.send(String::new());
|
||||
return;
|
||||
}
|
||||
monero::close_wallet(&w_orid, &wallet_password).await;
|
||||
|
@ -1853,7 +1853,7 @@ fn send_prepare_info_req(
|
|||
);
|
||||
// Request adjudicator and vendor while we're at it
|
||||
// Will coordinating send this on make requests next
|
||||
let s = db::Interface::async_open().await;
|
||||
let s = db::DatabaseEnvironment::async_open().await;
|
||||
let m_msig_key = format!(
|
||||
"{}-{}-{}",
|
||||
message::PREPARE_MSIG,
|
||||
|
@ -1866,9 +1866,9 @@ fn send_prepare_info_req(
|
|||
String::from(&v_orid),
|
||||
vendor
|
||||
);
|
||||
let m_prepare = db::Interface::async_read(&s.env, &s.handle, &m_msig_key).await;
|
||||
let v_prepare = db::Interface::async_read(&s.env, &s.handle, &v_msig_key).await;
|
||||
if v_prepare == utils::empty_string() {
|
||||
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;
|
||||
if v_prepare.is_empty() {
|
||||
log::debug!(
|
||||
"constructing vendor {} msig messages",
|
||||
message::PREPARE_MSIG
|
||||
|
@ -1883,7 +1883,7 @@ fn send_prepare_info_req(
|
|||
};
|
||||
let _v_result = message::d_trigger_msig_info(&vendor, &v_jwp, &v_msig_request).await;
|
||||
}
|
||||
if m_prepare == utils::empty_string() {
|
||||
if m_prepare.is_empty() {
|
||||
log::debug!(
|
||||
"constructing adjudicator {} msig messages",
|
||||
message::PREPARE_MSIG
|
||||
|
@ -1921,12 +1921,12 @@ fn send_make_info_req(
|
|||
);
|
||||
let v_jwp: String =
|
||||
utils::search_gui_db(String::from(crate::GUI_JWP_DB_KEY), String::from(&vendor));
|
||||
let wallet_password = utils::empty_string();
|
||||
let wallet_password = String::new();
|
||||
let m_wallet = monero::open_wallet(&w_orid, &wallet_password).await;
|
||||
if !m_wallet {
|
||||
monero::close_wallet(&w_orid, &wallet_password).await;
|
||||
log::error!("failed to open wallet");
|
||||
let _ = tx.send(utils::empty_string());
|
||||
let _ = tx.send(String::new());
|
||||
return;
|
||||
}
|
||||
let mut prepare_info_prep = Vec::new();
|
||||
|
@ -1938,7 +1938,7 @@ fn send_make_info_req(
|
|||
String::from(crate::GUI_MSIG_PREPARE_DB_KEY),
|
||||
String::from(&w_orid),
|
||||
);
|
||||
let s = db::Interface::async_open().await;
|
||||
let s = db::DatabaseEnvironment::async_open().await;
|
||||
let m_msig_key = format!(
|
||||
"{}-{}-{}",
|
||||
message::PREPARE_MSIG,
|
||||
|
@ -1951,8 +1951,8 @@ fn send_make_info_req(
|
|||
String::from(&v_orid),
|
||||
vendor
|
||||
);
|
||||
let m_prepare = db::Interface::async_read(&s.env, &s.handle, &m_msig_key).await;
|
||||
let v_prepare = db::Interface::async_read(&s.env, &s.handle, &v_msig_key).await;
|
||||
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));
|
||||
|
@ -1963,11 +1963,11 @@ fn send_make_info_req(
|
|||
String::from(crate::GUI_MSIG_MAKE_DB_KEY),
|
||||
String::from(&w_orid),
|
||||
);
|
||||
if local_make == utils::empty_string() {
|
||||
if local_make.is_empty() {
|
||||
let make_info = monero::make_wallet(prepare_info_prep).await;
|
||||
monero::close_wallet(&w_orid, &wallet_password).await;
|
||||
let ref_make_info: &String = &make_info.result.multisig_info;
|
||||
if String::from(ref_make_info) != utils::empty_string() {
|
||||
if !String::from(ref_make_info).is_empty() {
|
||||
utils::write_gui_db(
|
||||
String::from(crate::GUI_MSIG_MAKE_DB_KEY),
|
||||
String::from(&w_orid),
|
||||
|
@ -1978,7 +1978,7 @@ fn send_make_info_req(
|
|||
// Request adjudicator and vendor while we're at it
|
||||
// Will coordinating send this on make requests next
|
||||
|
||||
let s = db::Interface::async_open().await;
|
||||
let s = db::DatabaseEnvironment::async_open().await;
|
||||
let m_msig_key = format!(
|
||||
"{}-{}-{}",
|
||||
message::MAKE_MSIG,
|
||||
|
@ -1991,9 +1991,9 @@ fn send_make_info_req(
|
|||
String::from(&v_orid),
|
||||
vendor
|
||||
);
|
||||
let m_make = db::Interface::async_read(&s.env, &s.handle, &m_msig_key).await;
|
||||
let v_make = db::Interface::async_read(&s.env, &s.handle, &v_msig_key).await;
|
||||
if v_make == utils::empty_string() {
|
||||
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;
|
||||
if v_make.is_empty() {
|
||||
log::debug!("constructing vendor {} msig messages", message::MAKE_MSIG);
|
||||
let v_msig_request: reqres::MultisigInfoRequest = reqres::MultisigInfoRequest {
|
||||
contact: i2p::get_destination(None),
|
||||
|
@ -2005,7 +2005,7 @@ fn send_make_info_req(
|
|||
};
|
||||
let _v_result = message::d_trigger_msig_info(&vendor, &v_jwp, &v_msig_request).await;
|
||||
}
|
||||
if m_make == utils::empty_string() {
|
||||
if m_make.is_empty() {
|
||||
log::debug!(
|
||||
"constructing adjudicator {} msig messages",
|
||||
message::MAKE_MSIG
|
||||
|
@ -2043,12 +2043,12 @@ fn send_kex_initial_req(
|
|||
);
|
||||
let v_jwp: String =
|
||||
utils::search_gui_db(String::from(crate::GUI_JWP_DB_KEY), String::from(&vendor));
|
||||
let wallet_password = utils::empty_string();
|
||||
let wallet_password = String::new();
|
||||
let m_wallet = monero::open_wallet(&w_orid, &wallet_password).await;
|
||||
if !m_wallet {
|
||||
monero::close_wallet(&w_orid, &wallet_password).await;
|
||||
log::error!("failed to open wallet");
|
||||
let _ = tx.send(utils::empty_string());
|
||||
let _ = tx.send(String::new());
|
||||
return;
|
||||
}
|
||||
let mut kex_init_prep = Vec::new();
|
||||
|
@ -2060,7 +2060,7 @@ fn send_kex_initial_req(
|
|||
String::from(crate::GUI_MSIG_MAKE_DB_KEY),
|
||||
String::from(&w_orid),
|
||||
);
|
||||
let s = db::Interface::async_open().await;
|
||||
let s = db::DatabaseEnvironment::async_open().await;
|
||||
let m_msig_key = format!(
|
||||
"{}-{}-{}",
|
||||
message::MAKE_MSIG,
|
||||
|
@ -2073,8 +2073,8 @@ fn send_kex_initial_req(
|
|||
String::from(&v_orid),
|
||||
vendor
|
||||
);
|
||||
let m_kex_init = db::Interface::async_read(&s.env, &s.handle, &m_msig_key).await;
|
||||
let v_kex_init = db::Interface::async_read(&s.env, &s.handle, &v_msig_key).await;
|
||||
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));
|
||||
m_kex_init_send.push(String::from(&c_kex_init));
|
||||
|
@ -2085,12 +2085,12 @@ fn send_kex_initial_req(
|
|||
String::from(crate::GUI_MSIG_KEX_ONE_DB_KEY),
|
||||
String::from(&w_orid),
|
||||
);
|
||||
if local_kex_init == utils::empty_string() {
|
||||
if local_kex_init.is_empty() {
|
||||
let kex_out =
|
||||
monero::exchange_multisig_keys(false, kex_init_prep, &wallet_password).await;
|
||||
monero::close_wallet(&w_orid, &wallet_password).await;
|
||||
let ref_kex_info: &String = &kex_out.result.multisig_info;
|
||||
if String::from(ref_kex_info) != utils::empty_string() {
|
||||
if !String::from(ref_kex_info).is_empty() {
|
||||
utils::write_gui_db(
|
||||
String::from(crate::GUI_MSIG_KEX_ONE_DB_KEY),
|
||||
String::from(&w_orid),
|
||||
|
@ -2100,7 +2100,7 @@ fn send_kex_initial_req(
|
|||
}
|
||||
// Request adjudicator and vendor while we're at it
|
||||
// Will coordinating send this on kex round two next
|
||||
let s = db::Interface::async_open().await;
|
||||
let s = db::DatabaseEnvironment::async_open().await;
|
||||
let m_msig_key = format!(
|
||||
"{}-{}-{}",
|
||||
message::KEX_ONE_MSIG,
|
||||
|
@ -2113,9 +2113,9 @@ fn send_kex_initial_req(
|
|||
String::from(&v_orid),
|
||||
vendor
|
||||
);
|
||||
let m_kex_init = db::Interface::async_read(&s.env, &s.handle, &m_msig_key).await;
|
||||
let v_kex_init = db::Interface::async_read(&s.env, &s.handle, &v_msig_key).await;
|
||||
if v_kex_init == utils::empty_string() {
|
||||
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;
|
||||
if v_kex_init.is_empty() {
|
||||
log::debug!(
|
||||
"constructing vendor {} msig messages",
|
||||
message::KEX_ONE_MSIG
|
||||
|
@ -2130,7 +2130,7 @@ fn send_kex_initial_req(
|
|||
};
|
||||
let _v_result = message::d_trigger_msig_info(&vendor, &v_jwp, &v_msig_request).await;
|
||||
}
|
||||
if m_kex_init == utils::empty_string() {
|
||||
if m_kex_init.is_empty() {
|
||||
log::debug!(
|
||||
"constructing adjudicator {} msig messages",
|
||||
message::KEX_ONE_MSIG
|
||||
|
@ -2168,12 +2168,12 @@ fn send_kex_final_req(
|
|||
);
|
||||
let v_jwp: String =
|
||||
utils::search_gui_db(String::from(crate::GUI_JWP_DB_KEY), String::from(&vendor));
|
||||
let wallet_password = utils::empty_string();
|
||||
let wallet_password = String::new();
|
||||
let m_wallet = monero::open_wallet(&w_orid, &wallet_password).await;
|
||||
if !m_wallet {
|
||||
monero::close_wallet(&w_orid, &wallet_password).await;
|
||||
log::error!("failed to open wallet");
|
||||
let _ = tx.send(utils::empty_string());
|
||||
let _ = tx.send(String::new());
|
||||
return;
|
||||
}
|
||||
let mut kex_final_prep = Vec::new();
|
||||
|
@ -2183,7 +2183,7 @@ fn send_kex_final_req(
|
|||
String::from(crate::GUI_MSIG_KEX_ONE_DB_KEY),
|
||||
String::from(&w_orid),
|
||||
);
|
||||
let s = db::Interface::async_open().await;
|
||||
let s = db::DatabaseEnvironment::async_open().await;
|
||||
let m_msig_key = format!(
|
||||
"{}-{}-{}",
|
||||
message::KEX_ONE_MSIG,
|
||||
|
@ -2196,8 +2196,8 @@ fn send_kex_final_req(
|
|||
String::from(&v_orid),
|
||||
vendor
|
||||
);
|
||||
let m_kex_final = db::Interface::async_read(&s.env, &s.handle, &m_msig_key).await;
|
||||
let v_kex_final = db::Interface::async_read(&s.env, &s.handle, &v_msig_key).await;
|
||||
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;
|
||||
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));
|
||||
|
@ -2208,12 +2208,12 @@ fn send_kex_final_req(
|
|||
String::from(crate::GUI_MSIG_KEX_TWO_DB_KEY),
|
||||
String::from(&w_orid),
|
||||
);
|
||||
if local_kex_final == utils::empty_string() {
|
||||
if local_kex_final.is_empty() {
|
||||
let kex_out =
|
||||
monero::exchange_multisig_keys(false, kex_final_prep, &wallet_password).await;
|
||||
monero::close_wallet(&w_orid, &wallet_password).await;
|
||||
let ref_kex_info: &String = &kex_out.result.address;
|
||||
if String::from(ref_kex_info) != utils::empty_string() {
|
||||
if !String::from(ref_kex_info).is_empty() {
|
||||
utils::write_gui_db(
|
||||
String::from(crate::GUI_MSIG_KEX_TWO_DB_KEY),
|
||||
String::from(&w_orid),
|
||||
|
@ -2222,7 +2222,7 @@ fn send_kex_final_req(
|
|||
}
|
||||
}
|
||||
// we can verify all good if the senders all send back the correct wallet address
|
||||
let s = db::Interface::async_open().await;
|
||||
let s = db::DatabaseEnvironment::async_open().await;
|
||||
let m_msig_key = format!(
|
||||
"{}-{}-{}",
|
||||
message::KEX_TWO_MSIG,
|
||||
|
@ -2235,9 +2235,9 @@ fn send_kex_final_req(
|
|||
String::from(&v_orid),
|
||||
vendor
|
||||
);
|
||||
let m_kex_final = db::Interface::async_read(&s.env, &s.handle, &m_msig_key).await;
|
||||
let v_kex_final = db::Interface::async_read(&s.env, &s.handle, &v_msig_key).await;
|
||||
if v_kex_final == utils::empty_string() {
|
||||
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;
|
||||
if v_kex_final.is_empty() {
|
||||
log::debug!(
|
||||
"constructing vendor {} msig messages",
|
||||
message::KEX_TWO_MSIG
|
||||
|
@ -2252,7 +2252,7 @@ fn send_kex_final_req(
|
|||
};
|
||||
let _v_result = message::d_trigger_msig_info(&vendor, &v_jwp, &v_msig_request).await;
|
||||
}
|
||||
if m_kex_final == utils::empty_string() {
|
||||
if m_kex_final.is_empty() {
|
||||
log::debug!(
|
||||
"constructing adjudicator {} msig messages",
|
||||
message::KEX_TWO_MSIG
|
||||
|
@ -2276,7 +2276,7 @@ fn send_kex_final_req(
|
|||
fn set_order_address(orid: &String, tx: Sender<reqres::XmrRpcAddressResponse>, ctx: egui::Context) {
|
||||
let order_id = String::from(orid);
|
||||
tokio::spawn(async move {
|
||||
let wallet_password = utils::empty_string();
|
||||
let wallet_password = String::new();
|
||||
monero::open_wallet(&order_id, &wallet_password).await;
|
||||
let address: reqres::XmrRpcAddressResponse = monero::get_address().await;
|
||||
monero::close_wallet(&order_id, &wallet_password).await;
|
||||
|
@ -2295,7 +2295,7 @@ fn verify_order_wallet_funded(
|
|||
let l_contact = String::from(contact);
|
||||
tokio::spawn(async move {
|
||||
log::info!("executing verify_order_wallet_funded");
|
||||
let wallet_password = utils::empty_string();
|
||||
let wallet_password = String::new();
|
||||
monero::open_wallet(&order_id, &wallet_password).await;
|
||||
let _ = monero::refresh().await;
|
||||
let pre_bal = monero::get_balance().await;
|
||||
|
@ -2334,12 +2334,12 @@ fn send_import_info_req(tx: Sender<String>, ctx: egui::Context, orid: &String, v
|
|||
tokio::spawn(async move {
|
||||
let v_jwp: String =
|
||||
utils::search_gui_db(String::from(crate::GUI_JWP_DB_KEY), String::from(&vendor));
|
||||
let wallet_password = utils::empty_string();
|
||||
let wallet_password = String::new();
|
||||
let m_wallet = monero::open_wallet(&w_orid, &wallet_password).await;
|
||||
if !m_wallet {
|
||||
log::error!("failed to open wallet");
|
||||
monero::close_wallet(&w_orid, &wallet_password).await;
|
||||
let _ = tx.send(utils::empty_string());
|
||||
let _ = tx.send(String::new());
|
||||
return;
|
||||
}
|
||||
let mut info: Vec<String> = Vec::new();
|
||||
|
@ -2353,15 +2353,15 @@ fn send_import_info_req(tx: Sender<String>, ctx: egui::Context, orid: &String, v
|
|||
);
|
||||
// Request vendor while we're at it
|
||||
// Will coordinating send this on make requests next
|
||||
let s = db::Interface::async_open().await;
|
||||
let s = db::DatabaseEnvironment::async_open().await;
|
||||
let v_msig_key = format!(
|
||||
"{}-{}-{}",
|
||||
message::EXPORT_MSIG,
|
||||
String::from(&v_orid),
|
||||
vendor
|
||||
);
|
||||
let v_export = db::Interface::async_read(&s.env, &s.handle, &v_msig_key).await;
|
||||
if v_export == utils::empty_string() {
|
||||
let v_export = db::DatabaseEnvironment::async_read(&s.env, &s.handle, &v_msig_key).await;
|
||||
if v_export.is_empty() {
|
||||
log::debug!("constructing vendor {} msig messages", message::EXPORT_MSIG);
|
||||
let v_msig_request: reqres::MultisigInfoRequest = reqres::MultisigInfoRequest {
|
||||
contact: i2p::get_destination(None),
|
||||
|
@ -2422,14 +2422,14 @@ fn validate_msig_step(
|
|||
vendor: &String,
|
||||
sub_type: &String,
|
||||
) -> bool {
|
||||
let s = db::Interface::open();
|
||||
let s = db::DatabaseEnvironment::open(&utils::get_release_env().value()).unwrap();
|
||||
let m_msig_key = format!("{}-{}-{}", sub_type, orid, adjudicator);
|
||||
let v_msig_key = format!("{}-{}-{}", sub_type, orid, vendor);
|
||||
let m_info = db::Interface::read(&s.env, &s.handle, &m_msig_key);
|
||||
let v_info = db::Interface::read(&s.env, &s.handle, &v_msig_key);
|
||||
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);
|
||||
log::debug!("{} adjudicator info: {}", sub_type, &m_info);
|
||||
log::debug!("{} vendor info: {}", sub_type, &v_info);
|
||||
m_info != utils::empty_string() && v_info != utils::empty_string()
|
||||
!m_info.is_empty() && !v_info.is_empty()
|
||||
}
|
||||
|
||||
fn release_txset(contact: String, orid: String, ctx: egui::Context, tx: Sender<bool>) {
|
||||
|
@ -2454,7 +2454,7 @@ fn upload_dinfo_req(dinfo: String, orid: String, ctx: egui::Context, tx: Sender<
|
|||
tokio::spawn(async move {
|
||||
log::info!("async upload_dinfo_req");
|
||||
let dinfo = order::upload_delivery_info(&orid, &dinfo).await;
|
||||
let _ = tx.send(dinfo.orid != utils::empty_string());
|
||||
let _ = tx.send(!dinfo.orid.is_empty());
|
||||
ctx.request_repaint();
|
||||
});
|
||||
}
|
||||
|
@ -2477,7 +2477,7 @@ fn create_dispute_req(
|
|||
let address_res = monero::get_address().await;
|
||||
monero::close_wallet(&wallet_name, &wallet_password).await;
|
||||
// generate a txset for the adjudicator
|
||||
let wallet_password = utils::empty_string();
|
||||
let wallet_password = String::new();
|
||||
monero::open_wallet(&d_orid, &wallet_password).await;
|
||||
let transfer = monero::sweep_all(String::from(address_res.result.address)).await;
|
||||
monero::close_wallet(&d_orid, &wallet_password).await;
|
||||
|
|
|
@ -22,7 +22,7 @@ impl Default for SettingsApp {
|
|||
fn default() -> Self {
|
||||
let (change_wallet_password_tx, change_wallet_password_rx) = std::sync::mpsc::channel();
|
||||
SettingsApp {
|
||||
credential: utils::empty_string(),
|
||||
credential: String::new(),
|
||||
change_wallet_password_rx,
|
||||
change_wallet_password_tx,
|
||||
is_loading: false,
|
||||
|
@ -63,20 +63,23 @@ impl eframe::App for SettingsApp {
|
|||
}
|
||||
if ui.button("Change").clicked() {
|
||||
self.is_loading = true;
|
||||
let s = db::Interface::open();
|
||||
|
||||
// TODO: don't open the database in the GUI
|
||||
|
||||
let s = db::DatabaseEnvironment::open(&utils::get_release_env().value()).unwrap();
|
||||
let k = CREDENTIAL_KEY;
|
||||
db::Interface::delete(&s.env, &s.handle, &k);
|
||||
db::DatabaseEnvironment::delete(&s.env, &s.handle, &k);
|
||||
let mut hasher = Sha512::new();
|
||||
hasher.update(self.credential.clone());
|
||||
let result = hasher.finalize();
|
||||
db::Interface::write(&s.env, &s.handle, &k, &hex::encode(&result[..]));
|
||||
db::write_chunks(&s.env, &s.handle, &k, &hex::encode(&result[..]));
|
||||
// update wallet rpc
|
||||
change_wallet_password(
|
||||
self.change_wallet_password_tx.clone(),
|
||||
&self.credential,
|
||||
ctx.clone(),
|
||||
);
|
||||
self.credential = utils::empty_string();
|
||||
self.credential = String::new();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -34,12 +34,12 @@ impl Default for WalletApp {
|
|||
is_showing_qr: false,
|
||||
is_showing_sweep_result: false,
|
||||
qr: egui_extras::RetainedImage::from_image_bytes("qr.png", &contents).unwrap(),
|
||||
sweep_address: utils::empty_string(),
|
||||
sweep_address: String::new(),
|
||||
xmr_address_rx,
|
||||
xmr_address_tx,
|
||||
xmr_sweep_all_rx,
|
||||
xmr_sweep_all_tx,
|
||||
s_xmr_address: utils::empty_string(),
|
||||
s_xmr_address: String::new(),
|
||||
x_xmr_sweep_res: Default::default(),
|
||||
}
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ impl eframe::App for WalletApp {
|
|||
.title_bar(false)
|
||||
.vscroll(true)
|
||||
.show(ctx, |ui| {
|
||||
if !self.is_qr_set && self.s_xmr_address != utils::empty_string() {
|
||||
if !self.is_qr_set && !self.s_xmr_address.is_empty() {
|
||||
let code = QrCode::new(&self.s_xmr_address.clone()).unwrap();
|
||||
let image = code.render::<Luma<u8>>().build();
|
||||
let file_path = format!(
|
||||
|
@ -135,7 +135,7 @@ impl eframe::App for WalletApp {
|
|||
ctx.clone(),
|
||||
self.sweep_address.clone(),
|
||||
);
|
||||
self.sweep_address = utils::empty_string();
|
||||
self.sweep_address = String::new();
|
||||
self.is_showing_sweep_result = true;
|
||||
self.is_loading = true;
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ pub struct LoginApp {
|
|||
|
||||
impl Default for LoginApp {
|
||||
fn default() -> Self {
|
||||
let credential = utils::empty_string();
|
||||
let credential = String::new();
|
||||
let is_cred_generated = false;
|
||||
let is_not_showing_password = true;
|
||||
LoginApp {
|
||||
|
@ -54,9 +54,9 @@ impl eframe::App for LoginApp {
|
|||
let mut hasher = Sha512::new();
|
||||
hasher.update(self.credential.clone());
|
||||
let result = hasher.finalize();
|
||||
let s = db::Interface::open();
|
||||
db::Interface::write(&s.env, &s.handle, k, &hex::encode(&result[..]));
|
||||
self.credential = utils::empty_string();
|
||||
let s = db::DatabaseEnvironment::open();
|
||||
db::DatabaseEnvironment::write(&s.env, &s.handle, k, &hex::encode(&result[..]));
|
||||
self.credential = String::new();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -236,9 +236,9 @@ 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::Interface::open();
|
||||
let r = db::Interface::read(&s.env, &s.handle, crate::CREDENTIAL_KEY);
|
||||
if r != utils::empty_string() {
|
||||
let s = db::DatabaseEnvironment::open(&utils::get_release_env().value()).unwrap();
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, crate::CREDENTIAL_KEY);
|
||||
if !r.is_empty() {
|
||||
self.state.is_cred_set = true;
|
||||
self.state.is_checking_cred = false;
|
||||
}
|
||||
|
@ -308,9 +308,9 @@ impl WrapApp {
|
|||
loop {
|
||||
log::debug!("check for cred");
|
||||
tokio::time::sleep(std::time::Duration::from_secs(5)).await;
|
||||
let s = db::Interface::open();
|
||||
let r = db::Interface::read(&s.env, &s.handle, crate::CREDENTIAL_KEY);
|
||||
if r == utils::empty_string() {
|
||||
let s = db::DatabaseEnvironment::open(&utils::get_release_env().value()).unwrap();
|
||||
let r = db::DatabaseEnvironment::read(&s.env, &s.handle, crate::CREDENTIAL_KEY);
|
||||
if r.is_empty() {
|
||||
log::debug!("credential not found");
|
||||
let _ = tx.send(false);
|
||||
ctx.request_repaint();
|
||||
|
|
|
@ -121,7 +121,7 @@ pub async fn retrieve_order(
|
|||
_jwp: proof::PaymentProof,
|
||||
) -> Custom<Json<models::Order>> {
|
||||
let m_order = order::secure_retrieval(&orid, &signature).await;
|
||||
if m_order.cid == utils::empty_string() {
|
||||
if m_order.cid.is_empty() {
|
||||
return Custom(Status::BadRequest, Json(Default::default()));
|
||||
}
|
||||
Custom(Status::Created, Json(m_order))
|
||||
|
@ -205,7 +205,7 @@ pub async fn trigger_nasr(
|
|||
_jwp: proof::PaymentProof,
|
||||
) -> Custom<Json<models::Order>> {
|
||||
let order: models::Order = order::d_trigger_ship_request(&vendor, &orid).await;
|
||||
if order.orid == utils::empty_string() {
|
||||
if order.orid.is_empty() {
|
||||
return Custom(Status::BadRequest, Json(Default::default()));
|
||||
}
|
||||
Custom(Status::Ok, Json(order))
|
||||
|
@ -223,7 +223,7 @@ pub async fn cancel_order(
|
|||
_jwp: proof::PaymentProof,
|
||||
) -> Custom<Json<models::Order>> {
|
||||
let m_order = order::cancel_order(&orid, &signature).await;
|
||||
if m_order.cid == utils::empty_string() {
|
||||
if m_order.cid.is_empty() {
|
||||
return Custom(Status::BadRequest, Json(Default::default()));
|
||||
}
|
||||
Custom(Status::Ok, Json(m_order))
|
||||
|
|
Loading…
Reference in a new issue