cli

Command-line interface for Radroots
git clone https://radroots.dev/git/cli.git
Log | Files | Refs | README | LICENSE

commit 196ee3e6493f8358da714bd7bf81093c7b03e18a
parent ab3fdc5c4c9f2a94eeb5c4762d3da578d5c2bf7a
Author: triesap <tyson@radroots.org>
Date:   Thu, 21 May 2026 05:27:38 +0000

validation: trust worker evidence by listing id

- surface validation receipt listing ids in machine-readable receipt tags
- bind trusted worker listing ids to the receipt listing marker instead of the root event
- add distinct listing request decision unit coverage
- validate with cargo fmt, focused validation receipt tests, and nix check/test

Diffstat:
Msrc/runtime/validation_receipt.rs | 106++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 102 insertions(+), 4 deletions(-)

diff --git a/src/runtime/validation_receipt.rs b/src/runtime/validation_receipt.rs @@ -116,6 +116,7 @@ pub struct ValidationReceiptEventView { pub struct ValidationReceiptTagsView { pub order_id: String, pub event_set_root: String, + pub listing_event_id: String, pub reducer_output_root: String, pub public_values_hash: String, pub proof_system: String, @@ -751,6 +752,7 @@ fn tags_view(tags: &RadrootsValidationReceiptTags) -> ValidationReceiptTagsView ValidationReceiptTagsView { order_id: tags.order_id.clone(), event_set_root: tags.event_set_root.clone(), + listing_event_id: tags.listing_event_id.clone(), reducer_output_root: tags.reducer_output_root.clone(), public_values_hash: tags.public_values_hash.clone(), proof_system: tags.proof_system.as_str().to_owned(), @@ -1226,7 +1228,7 @@ fn worker_payload_binds_receipt( && payload.receipt_kind == Some(KIND_TRADE_VALIDATION_RECEIPT) && payload.receipt_event_id == binding.receipt_event_id && payload.order_id.as_deref() == Some(tags.order_id.as_str()) - && payload.listing_event_id.as_deref() == Some(tags.root_event_id.as_str()) + && payload.listing_event_id.as_deref() == Some(tags.listing_event_id.as_str()) && payload.event_set_root.as_deref() == Some(tags.event_set_root.as_str()) && payload.reducer_output_root.as_deref() == Some(tags.reducer_output_root.as_str()) && payload.request_event_id.as_deref() == Some(tags.root_event_id.as_str()) @@ -1290,13 +1292,17 @@ fn relay_failures(failures: Vec<DirectRelayFailure>) -> Vec<RelayFailureView> { mod tests { use super::{ ValidationReceiptWorkerEvidenceSelection, ValidationReceiptWorkerEvidenceView, + ValidationReceiptWorkerResultPayload, WorkerEvidenceReceiptBinding, proof_verification_view_for_receipt, validation_receipt_invalid_reason_code, + worker_payload_binds_receipt, }; + use radroots_events::kinds::KIND_TRADE_VALIDATION_RECEIPT; use radroots_trade::validation_receipt::{ RadrootsTradeValidationReceipt, RadrootsValidationReceiptError, RadrootsValidationReceiptProof, RadrootsValidationReceiptProofSystem, RadrootsValidationReceiptResult, RadrootsValidationReceiptStatement, - RadrootsValidationReceiptType, VALIDATION_RECEIPT_DOMAIN, VALIDATION_RECEIPT_VERSION, + RadrootsValidationReceiptTags, RadrootsValidationReceiptType, VALIDATION_RECEIPT_DOMAIN, + VALIDATION_RECEIPT_VERSION, }; fn sp1_proof_with_material() -> RadrootsValidationReceiptProof { @@ -1332,9 +1338,11 @@ mod tests { receipt_type: RadrootsValidationReceiptType::TradeTransition, result: RadrootsValidationReceiptResult::Valid, statement: RadrootsValidationReceiptStatement { - root_event_id: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + listing_event_id: + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa".to_owned(), + root_event_id: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" .to_owned(), - target_event_id: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + target_event_id: "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" .to_owned(), statement_type: RadrootsValidationReceiptType::TradeTransition, }, @@ -1353,6 +1361,96 @@ mod tests { }) } + fn receipt_tags() -> RadrootsValidationReceiptTags { + RadrootsValidationReceiptTags { + event_set_root: "0x2222222222222222222222222222222222222222222222222222222222222222" + .to_owned(), + listing_event_id: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + .to_owned(), + order_id: "order-1".to_owned(), + proof_system: RadrootsValidationReceiptProofSystem::None, + public_values_hash: + "0x5555555555555555555555555555555555555555555555555555555555555555".to_owned(), + receipt_type: RadrootsValidationReceiptType::TradeTransition, + reducer_output_root: + "0x3333333333333333333333333333333333333333333333333333333333333333".to_owned(), + root_event_id: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + .to_owned(), + target_event_id: "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + .to_owned(), + } + } + + fn worker_result_payload(listing_event_id: &str) -> ValidationReceiptWorkerResultPayload { + ValidationReceiptWorkerResultPayload { + cryptographic_proof_verified: false, + decision_event_id: Some( + "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc".to_owned(), + ), + event_set_root: Some( + "0x2222222222222222222222222222222222222222222222222222222222222222".to_owned(), + ), + listing_event_id: Some(listing_event_id.to_owned()), + order_id: Some("order-1".to_owned()), + proof_generated: false, + proof_mode: "none".to_owned(), + proof_system: "none".to_owned(), + public_values_hash: + "0x5555555555555555555555555555555555555555555555555555555555555555".to_owned(), + prover_backend: "local_execute".to_owned(), + receipt_kind: Some(KIND_TRADE_VALIDATION_RECEIPT), + receipt_event_id: "receipt-1".to_owned(), + reducer_output_root: Some( + "0x3333333333333333333333333333333333333333333333333333333333333333".to_owned(), + ), + request_event_id: Some( + "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb".to_owned(), + ), + sp1_execute_checked: true, + sp1_execute_public_values_hash: Some( + "0x5555555555555555555555555555555555555555555555555555555555555555".to_owned(), + ), + status: "succeeded".to_owned(), + worker_role: Some("non_authoritative_prover".to_owned()), + } + } + + #[test] + fn worker_evidence_binds_distinct_listing_request_and_decision_ids() { + let receipt = deterministic_receipt(); + let tags = receipt_tags(); + let binding = WorkerEvidenceReceiptBinding { + receipt_event_id: "receipt-1", + receipt: &receipt, + tags: &tags, + }; + + assert!(worker_payload_binds_receipt( + &worker_result_payload( + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + ), + &binding + )); + } + + #[test] + fn worker_evidence_rejects_listing_id_mismatch() { + let receipt = deterministic_receipt(); + let tags = receipt_tags(); + let binding = WorkerEvidenceReceiptBinding { + receipt_event_id: "receipt-1", + receipt: &receipt, + tags: &tags, + }; + + assert!(!worker_payload_binds_receipt( + &worker_result_payload( + "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd" + ), + &binding + )); + } + #[test] fn none_receipts_report_deterministic_verification_without_crypto_claim() { let view = proof_verification_view_for_receipt(