From d8bfe2a2ac1ba1f5177c3ba706d417b637c5da5c Mon Sep 17 00:00:00 2001 From: Uncle Stinky Date: Sat, 26 Sep 2026 15:13:07 +0300 Subject: [PATCH] correct replay check logic and secure unsigned thread validation Signed-off-by: Uncle Stinky --- pallets/weaver/Cargo.toml | 2 +- pallets/weaver/src/lib.rs | 40 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/pallets/weaver/Cargo.toml b/pallets/weaver/Cargo.toml index 3b72278..03124ec 100644 --- a/pallets/weaver/Cargo.toml +++ b/pallets/weaver/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ghost-weaver" -version = "0.0.15" +version = "0.0.16" description = "Weaving a secure cryptographic tapestry across different external chains." license.workspace = true authors.workspace = true diff --git a/pallets/weaver/src/lib.rs b/pallets/weaver/src/lib.rs index 766ec07..65a49ba 100644 --- a/pallets/weaver/src/lib.rs +++ b/pallets/weaver/src/lib.rs @@ -616,6 +616,21 @@ pub mod pallet { .propagate(true) .build() } + Call::pull_thread { + network_id, + session, + thread_proof, + } => { + let thread_context = + Self::validate_thread(network_id, session, thread_proof)?; + + ValidTransaction::with_tag_prefix("WeaverThread") + .priority(T::UnsignedPriority::get()) + .and_provides(thread_context.encode()) + .longevity(LOCK_BLOCK_EXPIRATION) + .propagate(true) + .build() + } _ => InvalidTransaction::Call.into(), } } @@ -623,6 +638,31 @@ pub mod pallet { } impl Pallet { + fn validate_thread( + network_id: &NetworkIdOf, + session: &WeavingSession, + thread_proof: &ThreadProof>, + ) -> Result { + let network_data = T::NetworkDataHandler::get(&network_id) + .ok_or(InvalidTransaction::BadProof)?; + + let root_hash = LoomStates::::get(&network_id, &session); + if root_hash == Default::default() { + return Err(InvalidTransaction::BadProof); + } + + thread_proof + .verify_thread_proof(root_hash, *network_id, &network_data.gatekeeper) + .ok_or(InvalidTransaction::BadProof)?; + + let pulled_thread_key = thread_proof.get_unique_key(*session, *network_id); + if PulledThreads::::contains_key(&pulled_thread_key) { + return Err(InvalidTransaction::Stale); + } + + Ok(pulled_thread_key) + } + fn validate_attestation_signature( attestation: &A, signature: &::Signature,