69 lines
3.6 KiB
Rust
69 lines
3.6 KiB
Rust
/* Completes or rejects an Iota-to-Iota relay without leaving retry state behind. */
|
|
use crate::storage_error::StorageError;
|
|
use crate::util::{db, sync};
|
|
use rusqlite::{OptionalExtension, params};
|
|
|
|
pub fn acknowledge_iota_delivery(
|
|
destination_iota: u64,
|
|
frame_id: u32,
|
|
signer_id: i64,
|
|
relay_message_id: &str,
|
|
destination_accepted_at: i64,
|
|
) -> Result<(), StorageError> {
|
|
let destination_iota = i64::try_from(destination_iota)
|
|
.map_err(|_| StorageError::Other("relay destination ID exceeds SQLite range".into()))?;
|
|
db::with_immediate_transaction(|tx| {
|
|
let pending_id = tx.query_row("SELECT id FROM pending_relays WHERE destination_id = ?1 AND target_kind = 1 AND frame_id = ?2", params![destination_iota, i64::from(frame_id)], |row| row.get::<_, i64>(0)).optional()?;
|
|
let Some(pending_id) = pending_id else {
|
|
return Ok(());
|
|
};
|
|
let message_id = tx.query_row("SELECT id FROM messages WHERE storage_owner = ?1 AND relay_signer_id = ?1 AND relay_message_id = ?2", params![signer_id, relay_message_id], |row| row.get::<_, i64>(0)).optional()?;
|
|
if let Some(message_id) = message_id {
|
|
tx.execute("UPDATE messages SET destination_iota_received_at = COALESCE(destination_iota_received_at, ?1), delivery_failed_at = NULL, delivery_failure = NULL, message_state = CASE WHEN message_state = 'sending' THEN 'sent' ELSE message_state END WHERE id = ?2", params![destination_accepted_at, message_id])?;
|
|
sync::record_event(
|
|
tx,
|
|
signer_id,
|
|
sync::EntityType::Message,
|
|
message_id,
|
|
sync::Operation::Upsert,
|
|
)?;
|
|
}
|
|
tx.execute("UPDATE relay_inbox SET state = 'delivered', downstream_acked_at = COALESCE(downstream_acked_at, ?3) WHERE signer_id = ?1 AND message_id = ?2", params![signer_id, relay_message_id, sync::now_millis()])?;
|
|
tx.execute("DELETE FROM pending_relays WHERE id = ?1", [pending_id])?;
|
|
Ok(())
|
|
})
|
|
}
|
|
|
|
pub fn reject_iota_delivery(
|
|
destination_iota: u64,
|
|
frame_id: u32,
|
|
signer_id: i64,
|
|
relay_message_id: &str,
|
|
failure: &str,
|
|
) -> Result<(), StorageError> {
|
|
let destination_iota = i64::try_from(destination_iota)
|
|
.map_err(|_| StorageError::Other("relay destination ID exceeds SQLite range".into()))?;
|
|
db::with_immediate_transaction(|tx| {
|
|
let pending_id = tx.query_row("SELECT id FROM pending_relays WHERE destination_id = ?1 AND target_kind = 1 AND frame_id = ?2", params![destination_iota, i64::from(frame_id)], |row| row.get::<_, i64>(0)).optional()?;
|
|
let Some(pending_id) = pending_id else {
|
|
return Ok(());
|
|
};
|
|
let message_id = tx.query_row("SELECT id FROM messages WHERE storage_owner = ?1 AND relay_signer_id = ?1 AND relay_message_id = ?2", params![signer_id, relay_message_id], |row| row.get::<_, i64>(0)).optional()?;
|
|
if let Some(message_id) = message_id {
|
|
tx.execute(
|
|
"UPDATE messages SET delivery_failed_at = ?1, delivery_failure = ?2 WHERE id = ?3",
|
|
params![sync::now_millis(), failure, message_id],
|
|
)?;
|
|
sync::record_event(
|
|
tx,
|
|
signer_id,
|
|
sync::EntityType::Message,
|
|
message_id,
|
|
sync::Operation::Upsert,
|
|
)?;
|
|
}
|
|
tx.execute("UPDATE relay_inbox SET state = 'rejected', rejected_at = COALESCE(rejected_at, ?3) WHERE signer_id = ?1 AND message_id = ?2", params![signer_id, relay_message_id, sync::now_millis()])?;
|
|
tx.execute("DELETE FROM pending_relays WHERE id = ?1", [pending_id])?;
|
|
Ok(())
|
|
})
|
|
}
|