coven_protocol/store_commit/
heads.rs1use super::*;
2
3#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
5#[serde(deny_unknown_fields)]
6pub struct StoreDeviceHeadBody {
7 pub store_root_hash: ObjectHash,
8 pub author_registration: StoreDeviceRegistrationRef,
9 pub commit: StoreBatchCommitRef,
10 pub successor: SuccessorLink,
11}
12
13impl SignedBody for StoreDeviceHeadBody {
14 const DOMAIN: &'static [u8] = HEAD_DOMAIN;
15}
16
17pub type StoreDeviceHead = Signed<StoreDeviceHeadBody>;
18
19impl StoreDeviceHead {
20 pub fn signed(
21 store_root_hash: ObjectHash,
22 author_registration: StoreDeviceRegistrationRef,
23 commit: StoreBatchCommitRef,
24 successor: SuccessorLink,
25 signer: &UserKeypair,
26 ) -> Result<Self, StoreProtocolError> {
27 if commit.coord.sequence() == 0 {
28 return Err(StoreProtocolError::InvalidSequence(0));
29 }
30 Ok(Signed::sign(
31 StoreDeviceHeadBody {
32 store_root_hash,
33 author_registration,
34 commit,
35 successor,
36 },
37 signer,
38 ))
39 }
40
41 pub fn head_hash(&self) -> ObjectHash {
42 self.hash()
43 }
44
45 pub fn slot_sequence(&self) -> u64 {
46 self.commit.coord.sequence()
47 }
48
49 pub fn signature_is_valid_for(&self, expected_registration: &StoreDeviceRegistration) -> bool {
50 self.verify_by(&expected_registration.device_signing_pubkey)
51 .is_ok()
52 }
53
54 pub fn parse_at(
55 bytes: &[u8],
56 expected_store_root_hash: ObjectHash,
57 expected_registration: &StoreDeviceRegistration,
58 expected_ref: &StoreBatchCommitRef,
59 ) -> Result<Self, StoreProtocolError> {
60 let head: Self = crate::objects::decode_protocol_object(bytes)?;
61 head.require_version()?;
62 crate::objects::verify_store_root(expected_store_root_hash, head.store_root_hash)?;
63 head.author_registration
64 .verify_registration(expected_registration)?;
65 if &head.commit != expected_ref {
66 return Err(StoreProtocolError::Malformed(
67 "Store head activates a different exact commit".to_string(),
68 ));
69 }
70 if head.commit.coord.sequence() == 0 {
71 return Err(StoreProtocolError::InvalidSequence(0));
72 }
73 if !head.signature_is_valid_for(expected_registration) {
74 return Err(StoreProtocolError::InvalidSignature);
75 }
76 Ok(head)
77 }
78}
79
80#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
81#[serde(deny_unknown_fields)]
82pub struct StoreDeviceHeadRef {
83 pub head_hash: ObjectHash,
84 pub object: ExactObjectRef,
85}