Skip to content

Commit 9e3998b

Browse files
committed
add DecryptionFailed in Event
1 parent c797cd1 commit 9e3998b

File tree

1 file changed

+55
-1
lines changed

1 file changed

+55
-1
lines changed

pallets/shield/src/lib.rs

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,11 @@ pub mod pallet {
142142
id: T::Hash,
143143
reason: DispatchErrorWithPostInfo<PostDispatchInfo>,
144144
},
145+
/// Decryption failed - validator could not decrypt the submission.
146+
DecryptionFailed {
147+
id: T::Hash,
148+
reason: BoundedVec<u8, ConstU32<256>>,
149+
},
145150
}
146151

147152
#[pallet::error]
@@ -404,6 +409,43 @@ pub mod pallet {
404409
}
405410
}
406411
}
412+
413+
/// Marks a submission as failed to decrypt and removes it from storage.
414+
///
415+
/// Called by the block author when decryption fails at any stage (e.g., ML-KEM decapsulate
416+
/// failed, AEAD decrypt failed, invalid ciphertext format, etc.). This allows clients to be
417+
/// notified of decryption failures through on-chain events.
418+
///
419+
/// # Arguments
420+
///
421+
/// * `id` - The wrapper id (hash of (author, commitment, ciphertext))
422+
/// * `reason` - Human-readable reason for the decryption failure (e.g., "ML-KEM decapsulate failed")
423+
#[pallet::call_index(3)]
424+
#[pallet::weight((
425+
Weight::from_parts(10_000_000, 0)
426+
.saturating_add(T::DbWeight::get().reads(1_u64))
427+
.saturating_add(T::DbWeight::get().writes(1_u64)),
428+
DispatchClass::Operational,
429+
Pays::No
430+
))]
431+
pub fn mark_decryption_failed(
432+
origin: OriginFor<T>,
433+
id: T::Hash,
434+
reason: BoundedVec<u8, ConstU32<256>>,
435+
) -> DispatchResult {
436+
// Unsigned: only the author node may inject this via ValidateUnsigned.
437+
ensure_none(origin)?;
438+
439+
// Load and consume the submission.
440+
let Some(_sub) = Submissions::<T>::take(id) else {
441+
return Err(Error::<T>::MissingSubmission.into());
442+
};
443+
444+
// Emit event to notify clients
445+
Self::deposit_event(Event::DecryptionFailed { id, reason });
446+
447+
Ok(())
448+
}
407449
}
408450

409451
impl<T: Config> Pallet<T> {
@@ -448,7 +490,19 @@ pub mod pallet {
448490
_ => InvalidTransaction::Call.into(),
449491
}
450492
}
451-
493+
Call::mark_decryption_failed { id, .. } => {
494+
match source {
495+
TransactionSource::Local | TransactionSource::InBlock => {
496+
ValidTransaction::with_tag_prefix("mev-shield-failed")
497+
.priority(u64::MAX)
498+
.longevity(64) // long because propagate(false)
499+
.and_provides(id) // dedupe by wrapper id
500+
.propagate(false) // CRITICAL: no gossip, stays on author node
501+
.build()
502+
}
503+
_ => InvalidTransaction::Call.into(),
504+
}
505+
}
452506
_ => InvalidTransaction::Call.into(),
453507
}
454508
}

0 commit comments

Comments
 (0)