36 lines
1.3 KiB
Rust
36 lines
1.3 KiB
Rust
//! SHA-256 hashed DAG chain, ported from dodrenett's lib/challenge.ts.
|
|||
|
|
//! Kept deliberately plain: every submission hashes in its parent(s), but
|
||
|
|
//! nothing here produces more than one parent yet - that only starts
|
||
|
|
//! mattering once something (an LLM, or a human) posts follow-up
|
||
|
|
//! questions back into a visitor's chain instead of the fixed content in
|
||
|
|
//! ../portal-content. The DAG-shaped `parent_hashes` field exists so that
|
||
|
|
//! can slot in later without a schema change; the hashing itself doesn't
|
||
|
|
//! need to.
|
||
|
|
#![cfg(feature = "ssr")]
|
||
|
|
|
||
|
|
use sha2::{Digest, Sha256};
|
||
|
|
|
||
|
|
/// Hashes one chain node from its question, its parent hash(es), the
|
||
|
|
/// submitted responses, and a timestamp. Parents are sorted first so the
|
||
|
|
/// hash doesn't depend on the order multiple parents happened to arrive
|
||
|
|
/// in.
|
||
|
|
pub fn hash_node(
|
||
|
|
question_id: &str,
|
||
|
|
parent_hashes: &[String],
|
||
|
|
responses: &serde_json::Value,
|
||
|
|
timestamp_ms: i64,
|
||
|
|
) -> String {
|
||
|
|
let mut parents = parent_hashes.to_vec();
|
||
|
|
parents.sort();
|
||
|
|
let payload = serde_json::json!({
|
||
|
|
"questionId": question_id,
|
||
|
|
"parentHashes": parents,
|
||
|
|
"responses": responses,
|
||
|
|
"timestamp": timestamp_ms,
|
||
|
|
});
|
||
|
|
let data = serde_json::to_vec(&payload).expect("json values always serialize");
|
||
|
|
let mut hasher = Sha256::new();
|
||
|
|
hasher.update(&data);
|
||
|
|
format!("{:x}", hasher.finalize())
|
||
|
|
}
|