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 CUSTOMER_ORDER_LIST_DB_KEY: &str = "olc";
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";
// End LMDB Keys

View file

@ -132,7 +132,7 @@ fn parse_multisig_message(mid: String) -> MultisigMessageData {
let values = decoded.split(":");
let mut v: Vec<String> = values.map(|s| String::from(s)).collect();
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
} else {
VALID_MSIG_MSG_LENGTH - 1
@ -143,8 +143,9 @@ fn parse_multisig_message(mid: String) -> MultisigMessageData {
let orid: String = v.remove(0);
let a_info: String = v.remove(0);
let mut info = String::from(&a_info);
// on prepare info customer only receives one set of info
if sub_type != TXSET_MSIG || !v.is_empty() {
// on prepare info and txset msig messages customer only receives one set of
// info
if !v.is_empty() {
let b_info: String = v.remove(0);
info = format!("{}:{}", a_info, b_info);
}
@ -197,10 +198,21 @@ pub async fn rx_multisig(m: Json<Message>) {
created: chrono::offset::Utc::now().timestamp(),
to: String::from(&m.to),
};
debug!("insert multisig message: {:?}", &new_message);
let s = db::Interface::open();
let s = db::Interface::async_open().await;
let k = &new_message.mid;
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);
debug!(
"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}
// 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);
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
@ -440,7 +453,7 @@ pub async fn retry_fts() {
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 m_type = if message.mid.contains("misg") {
let m_type = if message.mid.contains("msig") {
MessageType::Multisig
} else {
MessageType::Normal
@ -467,7 +480,14 @@ fn is_fts_clear(r: String) -> bool {
let v_mid = r.split(",");
let v: Vec<String> = v_mid.map(|s| String::from(s)).collect();
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
@ -623,7 +643,7 @@ pub async fn d_trigger_msig_info(
};
let pre = trigger_msig_info_request(d_contact, d_jwp, d_request).await;
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();
}
pre.unwrap_or(Default::default())

View file

@ -549,7 +549,9 @@ pub async fn start_up() {
let mut wallet_password =
std::env::var(crate::MONERO_WALLET_PASSWORD).unwrap_or(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();
wallet_password = read_password().unwrap();
std::env::set_var(crate::MONERO_WALLET_PASSWORD, &wallet_password);

View file

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