Break down parse_network_msg into parse_new_tx, parse_cipher
This commit is contained in:
parent
ec47592581
commit
b2cab53188
166
src/api.rs
166
src/api.rs
@ -474,7 +474,7 @@ pub fn reset_device() -> ApiResult<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_recover_transaction(
|
fn handle_transaction(
|
||||||
updated: HashMap<OutPoint, OwnedOutput>,
|
updated: HashMap<OutPoint, OwnedOutput>,
|
||||||
tx: &Transaction,
|
tx: &Transaction,
|
||||||
sp_wallet: &mut SpWallet,
|
sp_wallet: &mut SpWallet,
|
||||||
@ -666,7 +666,7 @@ fn process_transaction(
|
|||||||
tx_hex: String,
|
tx_hex: String,
|
||||||
blockheight: u32,
|
blockheight: u32,
|
||||||
tweak_data_hex: String,
|
tweak_data_hex: String,
|
||||||
) -> anyhow::Result<CachedMessage> {
|
) -> anyhow::Result<Option<CachedMessage>> {
|
||||||
let tx = deserialize::<Transaction>(&Vec::from_hex(&tx_hex)?)?;
|
let tx = deserialize::<Transaction>(&Vec::from_hex(&tx_hex)?)?;
|
||||||
|
|
||||||
let tweak_data = PublicKey::from_str(&tweak_data_hex)?;
|
let tweak_data = PublicKey::from_str(&tweak_data_hex)?;
|
||||||
@ -676,105 +676,83 @@ fn process_transaction(
|
|||||||
let updated = wallet.update_wallet_with_transaction(&tx, blockheight, tweak_data)?;
|
let updated = wallet.update_wallet_with_transaction(&tx, blockheight, tweak_data)?;
|
||||||
|
|
||||||
if updated.len() > 0 {
|
if updated.len() > 0 {
|
||||||
let updated_msg = handle_recover_transaction(updated, &tx, wallet, tweak_data)?;
|
let updated_msg = handle_transaction(updated, &tx, wallet, tweak_data)?;
|
||||||
return Ok(updated_msg);
|
return Ok(Some(updated_msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(anyhow::Error::msg("No output found"))
|
Ok(None)
|
||||||
}
|
|
||||||
|
|
||||||
fn process_new_tx_error(msg: NewTxMessage) -> anyhow::Result<CachedMessage> {
|
|
||||||
// how do we match this error with the cached message?
|
|
||||||
unimplemented!();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn parse_network_msg(raw: String, fee_rate: u32) -> ApiResult<CachedMessage> {
|
pub fn parse_new_tx(new_tx_msg: String, block_height: u32, fee_rate: u32) -> ApiResult<Option<CachedMessage>> {
|
||||||
if let Ok(ank_msg) = serde_json::from_str::<AnkNetworkMsg>(&raw) {
|
let new_tx: NewTxMessage = serde_json::from_str(&new_tx_msg)?;
|
||||||
match ank_msg.flag {
|
|
||||||
AnkFlag::NewTx => {
|
if let Some(error) = new_tx.error {
|
||||||
let tx_message = serde_json::from_str::<NewTxMessage>(&ank_msg.content)?;
|
return Err(ApiError {
|
||||||
if let Some(ref error) = tx_message.error {
|
message: format!("NewTx returned with an error: {}", error),
|
||||||
// Transaction failed to broadcast
|
});
|
||||||
// we can retry later or check the availability of our spent output, depending on the actual error
|
}
|
||||||
// we should probably look up the cached message and record the error
|
|
||||||
log::error!("{}", error);
|
if new_tx.tweak_data.is_none() {
|
||||||
// let updated = process_new_tx_error(tx_message)?;
|
return Err(ApiError {
|
||||||
let updated = CachedMessage::new();
|
message: "Missing tweak_data".to_owned(),
|
||||||
return Ok(updated);
|
});
|
||||||
}
|
}
|
||||||
if tx_message.tweak_data.is_none() {
|
|
||||||
return Err(ApiError {
|
let msg =
|
||||||
message: "Missing tweak_data".to_owned(),
|
process_transaction(new_tx.transaction, block_height, new_tx.tweak_data.unwrap())?;
|
||||||
});
|
|
||||||
}
|
Ok(msg)
|
||||||
let network_msg =
|
}
|
||||||
process_transaction(tx_message.transaction, 0, tx_message.tweak_data.unwrap())?;
|
|
||||||
return Ok(network_msg);
|
#[wasm_bindgen]
|
||||||
}
|
pub fn parse_cipher(cipher_msg: String, fee_rate: u32) -> ApiResult<CachedMessage> {
|
||||||
AnkFlag::Faucet => {
|
// let's try to decrypt with keys we found in transactions but haven't used yet
|
||||||
let faucet_msg = serde_json::from_str::<FaucetMessage>(&ank_msg.content)?;
|
let mut messages = lock_messages()?;
|
||||||
if let Some(error) = faucet_msg.error {
|
let cipher = Vec::from_hex(&cipher_msg.trim_matches('\"'))?;
|
||||||
debug!("Faucet msg returned with an error: {}", error);
|
if let Some(message) = messages.iter_mut().find(|m| match m.status {
|
||||||
}
|
CachedMessageStatus::TxWaitingCipher | CachedMessageStatus::Trusted => {
|
||||||
unimplemented!();
|
m.try_decrypt_cipher(cipher.clone()).is_ok()
|
||||||
}
|
|
||||||
AnkFlag::Cipher => {
|
|
||||||
// let's try to decrypt with keys we found in transactions but haven't used yet
|
|
||||||
let mut messages = lock_messages()?;
|
|
||||||
let cipher = Vec::from_hex(&ank_msg.content.trim_matches('\"'))?;
|
|
||||||
if let Some(message) = messages.iter_mut().find(|m| match m.status {
|
|
||||||
CachedMessageStatus::TxWaitingCipher | CachedMessageStatus::Trusted => {
|
|
||||||
m.try_decrypt_cipher(cipher.clone()).is_ok()
|
|
||||||
}
|
|
||||||
_ => return false,
|
|
||||||
}) {
|
|
||||||
let plain = message.try_decrypt_cipher(cipher).unwrap();
|
|
||||||
debug!("Found message {}", String::from_utf8(plain.clone())?);
|
|
||||||
if message.status == CachedMessageStatus::TxWaitingCipher {
|
|
||||||
let cipher_msg: CipherMessage = serde_json::from_slice(&plain)?;
|
|
||||||
// does the retrieved message match with the commited hash?
|
|
||||||
let hash = create_commitment(serde_json::to_string(&cipher_msg)?);
|
|
||||||
if Some(hash) != message.commitment {
|
|
||||||
return Err(ApiError {
|
|
||||||
message: "Message doesn't match commitment".to_owned(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
message.sender = Some(cipher_msg.sender);
|
|
||||||
message.ciphertext = None;
|
|
||||||
if cipher_msg.message.starts_with("PAIRING") {
|
|
||||||
// we don't follow the classic confirmation pattern
|
|
||||||
// set the status to sth else
|
|
||||||
// if we agree, we must send another notification to remote
|
|
||||||
// the notification output here will be spent as our first session
|
|
||||||
message.status = CachedMessageStatus::Pairing;
|
|
||||||
} else if cipher_msg.message.starts_with("LOGIN") {
|
|
||||||
message.status = CachedMessageStatus::Login;
|
|
||||||
} else {
|
|
||||||
message.status = CachedMessageStatus::ReceivedMustConfirm;
|
|
||||||
}
|
|
||||||
message.plaintext.push(cipher_msg.message);
|
|
||||||
} else {
|
|
||||||
// We're receiving a message for some action already engaged
|
|
||||||
// Let's update the message by pushing what we just found out
|
|
||||||
message.plaintext.push(String::from_utf8(plain)?);
|
|
||||||
}
|
|
||||||
return Ok(message.clone());
|
|
||||||
} else {
|
|
||||||
// let's keep it in case we receive the transaction later
|
|
||||||
let mut new_msg = CachedMessage::new();
|
|
||||||
new_msg.status = CachedMessageStatus::CipherWaitingTx;
|
|
||||||
new_msg.ciphertext = Some(ank_msg.content);
|
|
||||||
messages.push(new_msg.clone());
|
|
||||||
return Ok(new_msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => unimplemented!(),
|
|
||||||
}
|
}
|
||||||
|
_ => return false,
|
||||||
|
}) {
|
||||||
|
let plain = message.try_decrypt_cipher(cipher).unwrap();
|
||||||
|
// debug!("Found message {}", String::from_utf8(plain.clone())?);
|
||||||
|
if message.status == CachedMessageStatus::TxWaitingCipher {
|
||||||
|
let cipher_msg: CipherMessage = serde_json::from_slice(&plain)?;
|
||||||
|
// does the retrieved message match with the commited hash?
|
||||||
|
let hash = create_commitment(serde_json::to_string(&cipher_msg)?);
|
||||||
|
if Some(hash) != message.commitment {
|
||||||
|
return Err(ApiError {
|
||||||
|
message: "Message doesn't match commitment".to_owned(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
message.sender = Some(cipher_msg.sender);
|
||||||
|
message.ciphertext = None;
|
||||||
|
if cipher_msg.message.starts_with("PAIRING") {
|
||||||
|
// we don't follow the classic confirmation pattern
|
||||||
|
// if we agree, we must send another notification to remote
|
||||||
|
// the notification output here will be spent as our first session
|
||||||
|
message.status = CachedMessageStatus::Pairing;
|
||||||
|
} else if cipher_msg.message.starts_with("LOGIN") {
|
||||||
|
message.status = CachedMessageStatus::Login;
|
||||||
|
} else {
|
||||||
|
message.status = CachedMessageStatus::ReceivedMustConfirm;
|
||||||
|
}
|
||||||
|
message.plaintext.push(cipher_msg.message);
|
||||||
|
} else {
|
||||||
|
// We're receiving a message for some action already engaged
|
||||||
|
// Let's update the message by pushing what we just found out
|
||||||
|
message.plaintext.push(String::from_utf8(plain)?);
|
||||||
|
}
|
||||||
|
return Ok(message.clone());
|
||||||
} else {
|
} else {
|
||||||
Err(ApiError {
|
// let's keep it in case we receive the transaction later
|
||||||
message: format!("Can't parse message as a valid 4nk message: {}", raw),
|
let mut new_msg = CachedMessage::new();
|
||||||
})
|
new_msg.status = CachedMessageStatus::CipherWaitingTx;
|
||||||
|
new_msg.ciphertext = Some(cipher_msg);
|
||||||
|
messages.push(new_msg.clone());
|
||||||
|
return Ok(new_msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user