[Fix] Durability
This commit is contained in:
parent
dd69b5bd97
commit
ec3f5e6a6e
9 changed files with 317 additions and 118 deletions
|
|
@ -40,6 +40,21 @@ const IOTA_KEYRING_PATH: &str = "iota.mk";
|
|||
static IDENTITY_PATH: std::sync::OnceLock<PathBuf> = std::sync::OnceLock::new();
|
||||
static OMIKRON_PUBLIC_KEY_PATH: std::sync::OnceLock<PathBuf> = std::sync::OnceLock::new();
|
||||
|
||||
fn record_origin_delivery_failure(signer_id: u64, relay_message_id: &str, failure: &str) {
|
||||
let Ok(storage_owner) = i64::try_from(signer_id) else {
|
||||
return;
|
||||
};
|
||||
if let Err(error) = chat_files::record_delivery_failure(
|
||||
storage_owner,
|
||||
storage_owner,
|
||||
relay_message_id,
|
||||
failure,
|
||||
now_millis_i64(),
|
||||
) {
|
||||
log!("Relay delivery failure storage failed: {error}");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Keeps identity and pinned Omikron key files independent from the process
|
||||
* working directory, so restarts use the same trusted material.
|
||||
|
|
@ -1136,6 +1151,11 @@ impl OmikronConnection {
|
|||
Ok(destination_iota) => destination_iota,
|
||||
Err(error) => {
|
||||
log!("Relay origin route lookup failed: {}", error);
|
||||
record_origin_delivery_failure(
|
||||
verified.context.signer_id,
|
||||
&verified.context.message_id,
|
||||
"destination_iota_not_found",
|
||||
);
|
||||
self.send_relay_response(frame.id(), CommunicationType::ErrorNoIota)
|
||||
.await;
|
||||
return;
|
||||
|
|
@ -1145,6 +1165,11 @@ impl OmikronConnection {
|
|||
Ok(value) => value,
|
||||
Err(error) => {
|
||||
log!("Relay origin forwarding validation failed: {}", error);
|
||||
record_origin_delivery_failure(
|
||||
verified.context.signer_id,
|
||||
&verified.context.message_id,
|
||||
"forwarding_validation_failed",
|
||||
);
|
||||
self.send_relay_response(frame.id(), CommunicationType::ErrorInvalidData)
|
||||
.await;
|
||||
return;
|
||||
|
|
@ -1154,6 +1179,11 @@ impl OmikronConnection {
|
|||
Ok(bytes) => bytes,
|
||||
Err(error) => {
|
||||
log!("Relay origin retry could not be serialized: {}", error);
|
||||
record_origin_delivery_failure(
|
||||
verified.context.signer_id,
|
||||
&verified.context.message_id,
|
||||
"serialization_failed",
|
||||
);
|
||||
self.send_relay_response(frame.id(), CommunicationType::ErrorInternal)
|
||||
.await;
|
||||
return;
|
||||
|
|
@ -1167,6 +1197,11 @@ impl OmikronConnection {
|
|||
&type_map_version,
|
||||
) {
|
||||
log!("Relay origin retry queue failed: {}", error);
|
||||
record_origin_delivery_failure(
|
||||
verified.context.signer_id,
|
||||
&verified.context.message_id,
|
||||
"queue_failed",
|
||||
);
|
||||
self.send_relay_response(frame.id(), CommunicationType::ErrorInternal)
|
||||
.await;
|
||||
return;
|
||||
|
|
@ -1242,6 +1277,11 @@ impl OmikronConnection {
|
|||
}
|
||||
Ok(response) => {
|
||||
log!("Relay origin route returned {}", response.get_type());
|
||||
record_origin_delivery_failure(
|
||||
verified.context.signer_id,
|
||||
&verified.context.message_id,
|
||||
"destination_rejected",
|
||||
);
|
||||
self.send_relay_response(
|
||||
frame.id(),
|
||||
response
|
||||
|
|
@ -1252,6 +1292,11 @@ impl OmikronConnection {
|
|||
}
|
||||
Err(error) => {
|
||||
log!("Relay origin forwarding failed: {}", error);
|
||||
record_origin_delivery_failure(
|
||||
verified.context.signer_id,
|
||||
&verified.context.message_id,
|
||||
"destination_unreachable",
|
||||
);
|
||||
self.send_relay_response(frame.id(), CommunicationType::ErrorInternal)
|
||||
.await;
|
||||
}
|
||||
|
|
@ -1521,7 +1566,6 @@ impl OmikronConnection {
|
|||
dispatch!(DeleteApp, handle_delete_app);
|
||||
dispatch!(ClientConnected, handle_client_connected);
|
||||
dispatch!(ClientStateAck, handle_client_state_ack);
|
||||
dispatch!(MessageState, handle_message_state);
|
||||
dispatch!(MessageEdit, handle_message_edit);
|
||||
dispatch!(MessageEditLive, handle_message_edit_live);
|
||||
dispatch!(MessageReactionAdd, handle_message_reaction_add);
|
||||
|
|
@ -1771,10 +1815,6 @@ impl OmikronConnection {
|
|||
.await;
|
||||
}
|
||||
|
||||
async fn handle_message_state(self: Arc<Self>, cv: &CommunicationValue) {
|
||||
message_handlers::handle_message_state(cv);
|
||||
}
|
||||
|
||||
fn mutation_live_message(
|
||||
ty: CommunicationType,
|
||||
request: &CommunicationValue,
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ fn sign_lifecycle_payload(
|
|||
async fn inspect_credential_account(
|
||||
connection: &dyn OmikronClient,
|
||||
credential: &TuCredential,
|
||||
) -> Result<(String, String), LifecycleUserError> {
|
||||
) -> Result<(String, String, i64), LifecycleUserError> {
|
||||
if credential.omega_host != omega_discovery::omega_host() {
|
||||
return Err(LifecycleUserError::OmegaHostMismatch);
|
||||
}
|
||||
|
|
@ -108,10 +108,16 @@ async fn inspect_credential_account(
|
|||
.as_str()
|
||||
.map(str::to_owned)
|
||||
.ok_or(LifecycleUserError::RemoteRejected)?;
|
||||
let created_at = response
|
||||
.get_data(DataType::CreatedAt)
|
||||
.as_signed_number()
|
||||
.and_then(|value| i64::try_from(value).ok())
|
||||
.filter(|value| *value > 0)
|
||||
.ok_or(LifecycleUserError::RemoteRejected)?;
|
||||
if public_key != public_key_bundle_to_base64(&credential.public_key_bundle()) {
|
||||
return Err(LifecycleUserError::RemoteRejected);
|
||||
}
|
||||
Ok((username, public_key))
|
||||
Ok((username, public_key, created_at))
|
||||
}
|
||||
|
||||
async fn credential_proof(
|
||||
|
|
@ -168,17 +174,17 @@ pub async fn attach_user_from_tu(
|
|||
) -> Result<UserProfile, LifecycleUserError> {
|
||||
let credential = TuCredential::parse(contents)
|
||||
.map_err(|error| LifecycleUserError::InvalidCredential(error.to_string()))?;
|
||||
let (username, public_key) = inspect_credential_account(connection, &credential).await?;
|
||||
let profile = UserProfile::new(
|
||||
let (username, public_key, created_at) =
|
||||
inspect_credential_account(connection, &credential).await?;
|
||||
let profile = UserProfile::new_with_created_at(
|
||||
credential.user_id,
|
||||
username,
|
||||
None,
|
||||
public_key,
|
||||
hex_hash(contents),
|
||||
String::new(),
|
||||
created_at,
|
||||
);
|
||||
write_user_credential(&profile.username, &credential.to_canonical_string())
|
||||
.map_err(|error| LifecycleUserError::LocalPersistence(error.to_string()))?;
|
||||
pending_operations::upsert(&PendingUserOperation {
|
||||
user_id: profile.user_id,
|
||||
operation: PendingUserOperationKind::Attach,
|
||||
|
|
@ -191,6 +197,13 @@ pub async fn attach_user_from_tu(
|
|||
created_at: now_millis(),
|
||||
})
|
||||
.map_err(|error| LifecycleUserError::LocalPersistence(error.to_string()))?;
|
||||
write_user_credential(&profile.username, &credential.to_canonical_string())
|
||||
.map_err(|error| LifecycleUserError::LocalPersistence(error.to_string()))?;
|
||||
pending_operations::update_phase(
|
||||
profile.user_id,
|
||||
PendingUserOperationPhase::CredentialWritten,
|
||||
)
|
||||
.map_err(|error| LifecycleUserError::LocalPersistence(error.to_string()))?;
|
||||
if let Err(error) = credential_proof(
|
||||
connection,
|
||||
&credential,
|
||||
|
|
|
|||
Loading…
Reference in a new issue