Skip to main content

chc_service/routes/
get_record_data.rs

1use std::sync::Arc;
2
3use axum::extract::{Path, State};
4use holochain::{
5    conductor::chc::{EncryptedEntry, GetRecordsRequest},
6    prelude::{ChainItem, Signature, SignedActionHashed},
7};
8
9use crate::{
10    chc::{AppState, CellState, RecordItem},
11    msgpack_utils::MsgPack,
12    ChcServiceError,
13};
14
15use super::ChcPathParams;
16
17pub type GetRecordDataResult = Vec<(SignedActionHashed, Option<(Arc<EncryptedEntry>, Signature)>)>;
18
19// XXX: Certain cases are not handled with this implementation
20//      1. No duplicate nonce checks, recent nonces are not stored in the cell state
21// .    2. `since_hash` is not validated
22#[tracing::instrument(skip(app_state, request))]
23pub async fn get_record_data(
24    Path(params): Path<ChcPathParams>,
25    State(app_state): State<Arc<AppState>>,
26    MsgPack(request): MsgPack<GetRecordsRequest>,
27) -> Result<MsgPack<GetRecordDataResult>, ChcServiceError> {
28    let cell_id = params.try_into()?;
29
30    let m = app_state.records.read();
31    let records = match m.get(&cell_id) {
32        Some(CellState { records, .. }) if records.is_empty() => {
33            return Err(ChcServiceError::HashNotFound(
34                "Hash was not found in the CHC".to_string(),
35            ))
36        }
37        Some(CellState { records, .. }) => records,
38        None => {
39            return Err(ChcServiceError::HashNotFound(
40                "Hash was not found in the CHC".to_string(),
41            ))
42        }
43    };
44
45    let records = if let Some(hash) = &request.payload.since_hash {
46        records
47            .iter()
48            .skip_while(|r| hash != r.action.get_hash())
49            .skip(1)
50            .cloned()
51            .collect()
52    } else {
53        records.clone()
54    };
55
56    let record_data = records
57        .into_iter()
58        .map(
59            |RecordItem {
60                 action,
61                 encrypted_entry,
62             }| (action, encrypted_entry),
63        )
64        .collect::<Vec<_>>();
65
66    Ok(MsgPack(record_data))
67}