simperby_repository/interpret/
push.rs

1use super::*;
2
3pub async fn test_push_eligibility(
4    raw: &RawRepository,
5    commit_hash: CommitHash,
6    branch_name: String,
7    timestamp: Timestamp,
8    signature: TypedSignature<(CommitHash, String, Timestamp)>,
9    _timestamp_to_test: Timestamp,
10) -> Result<bool, Error> {
11    let reserved_state = raw.read_reserved_state().await?;
12    let signer = signature.signer();
13    let is_member = reserved_state
14        .members
15        .iter()
16        .find(|member| member.public_key == *signer)
17        .map(|member| !member.expelled)
18        .unwrap_or(false);
19    let is_valid_signature = signature
20        .verify(&(commit_hash, branch_name.clone(), timestamp))
21        .is_ok();
22    let is_eligible = is_member && is_valid_signature;
23    let is_eligible = is_eligible
24        && signature
25            .verify(&(commit_hash, branch_name, timestamp))
26            .is_ok();
27    // TODO: put the threshold in the config.
28    // let is_eligible = is_eligible && (timestamp_to_test - timestamp).abs() <= 1000;
29    Ok(is_eligible)
30}
31
32pub async fn broadcast(
33    raw: &mut RawRepository,
34    private_key: Option<PrivateKey>,
35) -> Result<(), Error> {
36    let agendas = read_agendas(raw).await?;
37    let agenda_proofs = read_governance_approved_agendas(raw).await?;
38    let blocks = read_blocks(raw).await?;
39
40    let mut commit_hashes = Vec::new();
41    commit_hashes.extend(agendas.iter().map(|&(commit_hash, _)| commit_hash));
42    commit_hashes.extend(agenda_proofs.iter().map(|&(commit_hash, _)| commit_hash));
43    commit_hashes.extend(blocks.iter().map(|&(commit_hash, _)| commit_hash));
44    commit_hashes.push(raw.locate_branch(FP_BRANCH_NAME.into()).await?);
45
46    let remotes = raw.list_remotes().await?;
47    for (remote_name, _) in remotes {
48        for &commit_hash in &commit_hashes {
49            let timestamp = get_timestamp();
50            let branch = &commit_hash
51                .to_hash256()
52                .aggregate(&timestamp.to_hash256())
53                .to_string()[0..BRANCH_NAME_HASH_DIGITS];
54            let signature = TypedSignature::sign(
55                &(commit_hash, branch.to_owned(), timestamp as u64),
56                private_key.as_ref().unwrap(),
57            )?;
58            let signer = serde_spb::to_string(signature.signer())?.replace('\"', "\\\"");
59            let signature =
60                serde_spb::to_string(&signature.get_raw_signature())?.replace('\"', "\\\"");
61
62            raw.create_branch(branch.into(), commit_hash).await?;
63            raw.push_option(
64                remote_name.clone(),
65                branch.into(),
66                Some(format!(
67                    "{commit_hash} {branch} {timestamp} {signature} {signer}"
68                )),
69            )
70            .await?;
71            raw.delete_branch(branch.into()).await?;
72        }
73    }
74    Ok(())
75}