p2panda_rs/entry/traits.rs
1// SPDX-License-Identifier: AGPL-3.0-or-later
2
3//! Interfaces for interactions for entry-like structs.
4use bamboo_rs_core_ed25519_yasmf::entry::is_lipmaa_required;
5
6use crate::entry::SIGNATURE_SIZE;
7use crate::entry::{LogId, SeqNum, Signature};
8use crate::hash::Hash;
9use crate::identity::PublicKey;
10
11/// Trait representing an "entry-like" struct.
12pub trait AsEntry {
13 /// Returns public key of entry.
14 fn public_key(&self) -> &PublicKey;
15
16 /// Returns log id of entry.
17 fn log_id(&self) -> &LogId;
18
19 /// Returns sequence number of entry.
20 fn seq_num(&self) -> &SeqNum;
21
22 /// Returns hash of skiplink entry when given.
23 fn skiplink(&self) -> Option<&Hash>;
24
25 /// Returns hash of backlink entry when given.
26 fn backlink(&self) -> Option<&Hash>;
27
28 /// Returns payload size of operation.
29 fn payload_size(&self) -> u64;
30
31 /// Returns payload hash of operation.
32 fn payload_hash(&self) -> &Hash;
33
34 /// Returns signature of entry.
35 fn signature(&self) -> &Signature;
36
37 /// Calculates sequence number of backlink entry.
38 fn seq_num_backlink(&self) -> Option<SeqNum> {
39 self.seq_num().backlink_seq_num()
40 }
41
42 /// Calculates sequence number of skiplink entry.
43 fn seq_num_skiplink(&self) -> Option<SeqNum> {
44 self.seq_num().skiplink_seq_num()
45 }
46
47 /// Returns true if skiplink has to be given.
48 fn is_skiplink_required(&self) -> bool {
49 is_lipmaa_required(self.seq_num().as_u64())
50 }
51}
52
53/// Trait representing an "encoded entry-like" struct.
54pub trait AsEncodedEntry {
55 /// Generates and returns hash of encoded entry.
56 fn hash(&self) -> Hash;
57
58 /// Returns entry as bytes.
59 ///
60 /// TODO: Do we want to change this method naming?
61 #[allow(clippy::wrong_self_convention)]
62 fn into_bytes(&self) -> Vec<u8>;
63
64 /// Returns payload size (number of bytes) of total encoded entry.
65 fn size(&self) -> u64;
66
67 /// Returns only those bytes of a signed entry that don't contain the signature.
68 ///
69 /// Encoded entries contains both a signature as well as the bytes that were signed. In order
70 /// to verify the signature you need access to only the bytes that were used during signing.
71 fn unsigned_bytes(&self) -> Vec<u8> {
72 let bytes = self.into_bytes();
73 let signature_offset = bytes.len() - SIGNATURE_SIZE;
74 bytes[..signature_offset].into()
75 }
76
77 /// Returns the entry bytes encoded as a hex string.
78 #[allow(clippy::wrong_self_convention)]
79 fn into_hex(&self) -> String {
80 hex::encode(self.into_bytes())
81 }
82}