complete prepare msig orchestration

This commit is contained in:
creating2morrow 2023-07-22 06:52:00 -04:00
parent 55d35d4206
commit d45995b006
4 changed files with 120 additions and 73 deletions

View file

@ -35,6 +35,7 @@ pub const RX_MESSAGE_DB_KEY: &str = "rx";
pub const FTS_DB_KEY: &str = "fts"; pub const FTS_DB_KEY: &str = "fts";
pub const CUSTOMER_ORDER_LIST_DB_KEY: &str = "olc"; pub const CUSTOMER_ORDER_LIST_DB_KEY: &str = "olc";
pub const MSIG_MESSAGE_DB_KEY: &str = "msig"; pub const MSIG_MESSAGE_DB_KEY: &str = "msig";
pub const MSIG_MESSAGE_LIST_DB_KEY: &str = "msigl";
pub const FTS_JWP_DB_KEY: &str = "fts-jwp"; pub const FTS_JWP_DB_KEY: &str = "fts-jwp";
// End LMDB Keys // End LMDB Keys

View file

@ -132,7 +132,7 @@ fn parse_multisig_message(mid: String) -> MultisigMessageData {
let values = decoded.split(":"); let values = decoded.split(":");
let mut v: Vec<String> = values.map(|s| String::from(s)).collect(); let mut v: Vec<String> = values.map(|s| String::from(s)).collect();
let sub_type: String = v.remove(0); let sub_type: String = v.remove(0);
let valid_length = if sub_type == TXSET_MSIG { let valid_length = if sub_type == TXSET_MSIG || sub_type == PREPARE_MSIG {
VALID_MSIG_MSG_LENGTH - 2 VALID_MSIG_MSG_LENGTH - 2
} else { } else {
VALID_MSIG_MSG_LENGTH - 1 VALID_MSIG_MSG_LENGTH - 1
@ -143,8 +143,9 @@ fn parse_multisig_message(mid: String) -> MultisigMessageData {
let orid: String = v.remove(0); let orid: String = v.remove(0);
let a_info: String = v.remove(0); let a_info: String = v.remove(0);
let mut info = String::from(&a_info); let mut info = String::from(&a_info);
// on prepare info customer only receives one set of info // on prepare info and txset msig messages customer only receives one set of
if sub_type != TXSET_MSIG || !v.is_empty() { // info
if !v.is_empty() {
let b_info: String = v.remove(0); let b_info: String = v.remove(0);
info = format!("{}:{}", a_info, b_info); info = format!("{}:{}", a_info, b_info);
} }
@ -197,10 +198,21 @@ pub async fn rx_multisig(m: Json<Message>) {
created: chrono::offset::Utc::now().timestamp(), created: chrono::offset::Utc::now().timestamp(),
to: String::from(&m.to), to: String::from(&m.to),
}; };
debug!("insert multisig message: {:?}", &new_message); let s = db::Interface::async_open().await;
let s = db::Interface::open();
let k = &new_message.mid; let k = &new_message.mid;
db::Interface::async_write(&s.env, &s.handle, k, &Message::to_db(&new_message)).await; db::Interface::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() {
debug!("creating msig message index");
}
let msg_list = [r, String::from(&f_mid)].join(",");
debug!(
"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;
let data: MultisigMessageData = parse_multisig_message(new_message.mid); let data: MultisigMessageData = parse_multisig_message(new_message.mid);
debug!( debug!(
"writing multisig message type {} for order {}", "writing multisig message type {} for order {}",
@ -208,8 +220,9 @@ pub async fn rx_multisig(m: Json<Message>) {
); );
// lookup msig message data by {type}-{order id}-{contact .b32.i2p address} // lookup msig message data by {type}-{order id}-{contact .b32.i2p address}
// store info as {a_info}:{a_info (optional)} // store info as {a_info}:{a_info (optional)}
let s_msig = db::Interface::async_open().await;
let msig_key = format!("{}-{}-{}", &data.sub_type, &data.orid, &m.from); let msig_key = format!("{}-{}-{}", &data.sub_type, &data.orid, &m.from);
db::Interface::async_write(&s.env, &s.handle, &msig_key, &data.info).await; db::Interface::async_write(&s_msig.env, &s_msig.handle, &msig_key, &data.info).await;
} }
/// Message lookup /// Message lookup
@ -440,7 +453,7 @@ pub async fn retry_fts() {
let k = format!("{}-{}", crate::FTS_JWP_DB_KEY, &message.to); let k = format!("{}-{}", crate::FTS_JWP_DB_KEY, &message.to);
let jwp = db::Interface::read(&s.env, &s.handle, &k); let jwp = db::Interface::read(&s.env, &s.handle, &k);
if jwp != utils::empty_string() { if jwp != utils::empty_string() {
let m_type = if message.mid.contains("misg") { let m_type = if message.mid.contains("msig") {
MessageType::Multisig MessageType::Multisig
} else { } else {
MessageType::Normal MessageType::Normal
@ -467,7 +480,14 @@ fn is_fts_clear(r: String) -> bool {
let v_mid = r.split(","); let v_mid = r.split(",");
let v: Vec<String> = v_mid.map(|s| String::from(s)).collect(); let v: Vec<String> = v_mid.map(|s| String::from(s)).collect();
debug!("fts contents: {:#?}", v); debug!("fts contents: {:#?}", v);
v.len() >= 2 && v[v.len() - 1] == utils::empty_string() && v[0] == utils::empty_string() let limit = v.len() <= 1;
if !limit {
return v.len() >= 2
&& v[v.len() - 1] == utils::empty_string()
&& v[0] == utils::empty_string();
} else {
return limit;
}
} }
/// Encrypts and sends the output from the monero-rpc /// Encrypts and sends the output from the monero-rpc
@ -623,7 +643,7 @@ pub async fn d_trigger_msig_info(
}; };
let pre = trigger_msig_info_request(d_contact, d_jwp, d_request).await; let pre = trigger_msig_info_request(d_contact, d_jwp, d_request).await;
if pre.is_err() { if pre.is_err() {
log::error!("faile to trigger {} info request", request.msig_type); log::error!("failed to trigger {} info request", request.msig_type);
return Default::default(); return Default::default();
} }
pre.unwrap_or(Default::default()) pre.unwrap_or(Default::default())

View file

@ -549,7 +549,9 @@ pub async fn start_up() {
let mut wallet_password = let mut wallet_password =
std::env::var(crate::MONERO_WALLET_PASSWORD).unwrap_or(empty_string()); std::env::var(crate::MONERO_WALLET_PASSWORD).unwrap_or(empty_string());
if wallet_password == empty_string() { if wallet_password == empty_string() {
print!("enter a password for monero-wallet-rpc: "); print!(
"MONERO_WALLET_PASSWORD not set, enter neveko wallet password for monero-wallet-rpc: "
);
std::io::stdout().flush().unwrap(); std::io::stdout().flush().unwrap();
wallet_password = read_password().unwrap(); wallet_password = read_password().unwrap();
std::env::set_var(crate::MONERO_WALLET_PASSWORD, &wallet_password); std::env::set_var(crate::MONERO_WALLET_PASSWORD, &wallet_password);

View file

@ -336,6 +336,7 @@ impl eframe::App for MarketApp {
} }
} }
}); });
if !self.msig.completed_prepare {
ui.horizontal(|ui| { ui.horizontal(|ui| {
ui.label("Prepare: \t\t\t\t\t"); ui.label("Prepare: \t\t\t\t\t");
if ui.button("Prepare").clicked() { if ui.button("Prepare").clicked() {
@ -344,7 +345,8 @@ impl eframe::App for MarketApp {
let vendor_prefix = String::from(crate::GUI_OVL_DB_KEY); let vendor_prefix = String::from(crate::GUI_OVL_DB_KEY);
let mediator = let mediator =
utils::search_gui_db(mediator_prefix, self.m_order.orid.clone()); utils::search_gui_db(mediator_prefix, self.m_order.orid.clone());
let vendor = utils::search_gui_db(vendor_prefix, self.m_order.orid.clone()); let vendor =
utils::search_gui_db(vendor_prefix, self.m_order.orid.clone());
// get prepare multisig info from vendor and mediator // get prepare multisig info from vendor and mediator
// call prepare multisig and save to db // call prepare multisig and save to db
send_prepare_info_req( send_prepare_info_req(
@ -360,15 +362,19 @@ impl eframe::App for MarketApp {
let vendor_prefix = String::from(crate::GUI_OVL_DB_KEY); let vendor_prefix = String::from(crate::GUI_OVL_DB_KEY);
let mediator = let mediator =
utils::search_gui_db(mediator_prefix, self.m_order.orid.clone()); utils::search_gui_db(mediator_prefix, self.m_order.orid.clone());
let vendor = utils::search_gui_db(vendor_prefix, self.m_order.orid.clone()); let vendor =
utils::search_gui_db(vendor_prefix, self.m_order.orid.clone());
let is_prepared = prepared_msg(&mediator, &self.m_order.orid, &vendor); let is_prepared = prepared_msg(&mediator, &self.m_order.orid, &vendor);
self.msig.completed_prepare = is_prepared; self.msig.completed_prepare = is_prepared;
} }
}); });
// ui.horizontal(|ui| { }
// ui.label("Make: \t\t\t\t\t\t"); if self.msig.completed_prepare {
// if ui.button("Make").clicked() {} ui.horizontal(|ui| {
// }); ui.label("Make: \t\t\t\t\t\t");
if ui.button("Make").clicked() {}
});
}
// ui.horizontal(|ui| { // ui.horizontal(|ui| {
// ui.label("Exchange Keys: \t\t"); // ui.label("Exchange Keys: \t\t");
// if ui.button("Exchange").clicked() {} // if ui.button("Exchange").clicked() {}
@ -1284,14 +1290,10 @@ fn send_prepare_info_req(
let v_orid: String = String::from(orid); let v_orid: String = String::from(orid);
let w_orid: String = String::from(orid); let w_orid: String = String::from(orid);
tokio::spawn(async move { tokio::spawn(async move {
let m_jwp: String = utils::search_gui_db( let m_jwp: String =
String::from(crate::GUI_JWP_DB_KEY), utils::search_gui_db(String::from(crate::GUI_JWP_DB_KEY), String::from(&mediator));
String::from(&mediator), let v_jwp: String =
); utils::search_gui_db(String::from(crate::GUI_JWP_DB_KEY), String::from(&vendor));
let v_jwp: String = utils::search_gui_db(
String::from(crate::GUI_JWP_DB_KEY),
String::from(&vendor),
);
let wallet_password = let wallet_password =
std::env::var(neveko_core::MONERO_WALLET_PASSWORD).unwrap_or(String::from("password")); std::env::var(neveko_core::MONERO_WALLET_PASSWORD).unwrap_or(String::from("password"));
monero::create_wallet(&w_orid, &wallet_password).await; monero::create_wallet(&w_orid, &wallet_password).await;
@ -1311,8 +1313,26 @@ fn send_prepare_info_req(
// Request mediator and vendor while we're at it // Request mediator and vendor while we're at it
// Will coordinating send this on make requests next // Will coordinating send this on make requests next
// TODO(c2m): check for partial completion to avoid duplicate requests let s = db::Interface::open();
log::debug!("constructing {} msig messages", message::PREPARE_MSIG); let m_msig_key = format!(
"{}-{}-{}",
message::PREPARE_MSIG,
String::from(&m_orid),
mediator
);
let v_msig_key = format!(
"{}-{}-{}",
message::PREPARE_MSIG,
String::from(&v_orid),
vendor
);
let m_prepare = db::Interface::read(&s.env, &s.handle, &m_msig_key);
let v_prepare = db::Interface::read(&s.env, &s.handle, &v_msig_key);
if v_prepare == utils::empty_string() {
log::debug!(
"constructing vendor {} msig messages",
message::PREPARE_MSIG
);
let v_msig_request: reqres::MultisigInfoRequest = reqres::MultisigInfoRequest { let v_msig_request: reqres::MultisigInfoRequest = reqres::MultisigInfoRequest {
contact: i2p::get_destination(None), contact: i2p::get_destination(None),
info: Vec::new(), info: Vec::new(),
@ -1321,6 +1341,12 @@ fn send_prepare_info_req(
orid: String::from(v_orid), orid: String::from(v_orid),
}; };
let _v_result = message::d_trigger_msig_info(&vendor, &v_jwp, &v_msig_request).await; let _v_result = message::d_trigger_msig_info(&vendor, &v_jwp, &v_msig_request).await;
}
if m_prepare == utils::empty_string() {
log::debug!(
"constructing mediator {} msig messages",
message::PREPARE_MSIG
);
let m_msig_request: reqres::MultisigInfoRequest = reqres::MultisigInfoRequest { let m_msig_request: reqres::MultisigInfoRequest = reqres::MultisigInfoRequest {
contact: i2p::get_destination(None), contact: i2p::get_destination(None),
info: Vec::new(), info: Vec::new(),
@ -1329,6 +1355,7 @@ fn send_prepare_info_req(
orid: String::from(m_orid), orid: String::from(m_orid),
}; };
let _m_result = message::d_trigger_msig_info(&mediator, &m_jwp, &m_msig_request).await; let _m_result = message::d_trigger_msig_info(&mediator, &m_jwp, &m_msig_request).await;
}
let _ = tx.send(String::from(ref_prepare_info)); let _ = tx.send(String::from(ref_prepare_info));
}); });
ctx.request_repaint(); ctx.request_repaint();
@ -1336,14 +1363,11 @@ fn send_prepare_info_req(
// End Async fn requests // End Async fn requests
fn prepared_msg(mediator: &String, orid: &String, vendor: &String,) -> bool { fn prepared_msg(mediator: &String, orid: &String, vendor: &String) -> bool {
let s = db::Interface::open(); let s = db::Interface::open();
let m_msig_key = format!("{}-{}-{}", message::PREPARE_MSIG, orid, mediator); let m_msig_key = format!("{}-{}-{}", message::PREPARE_MSIG, orid, mediator);
let v_msig_key = format!("{}-{}-{}", message::PREPARE_MSIG, orid, vendor); let v_msig_key = format!("{}-{}-{}", message::PREPARE_MSIG, orid, vendor);
let m_prepare = db::Interface::read(&s.env, &s.handle, &m_msig_key); let m_prepare = db::Interface::read(&s.env, &s.handle, &m_msig_key);
let v_prepare = db::Interface::read(&s.env, &s.handle, &v_msig_key); let v_prepare = db::Interface::read(&s.env, &s.handle, &v_msig_key);
log::debug!("mediator prepare info: {}", &m_prepare);
log::debug!("vendor prepare info: {}", &v_prepare);
m_prepare != utils::empty_string() && v_prepare != utils::empty_string() m_prepare != utils::empty_string() && v_prepare != utils::empty_string()
} }