fips_core/tree/
declaration.rs1use secp256k1::XOnlyPublicKey;
4use secp256k1::schnorr::Signature;
5use std::fmt;
6
7use super::TreeError;
8use crate::{Identity, NodeAddr};
9
10#[derive(Clone)]
17pub struct ParentDeclaration {
18 node_addr: NodeAddr,
20 parent_id: NodeAddr,
22 sequence: u64,
24 timestamp: u64,
26 signature: Option<Signature>,
28}
29
30impl ParentDeclaration {
31 pub fn new(node_addr: NodeAddr, parent_id: NodeAddr, sequence: u64, timestamp: u64) -> Self {
35 Self {
36 node_addr,
37 parent_id,
38 sequence,
39 timestamp,
40 signature: None,
41 }
42 }
43
44 pub fn self_root(node_addr: NodeAddr, sequence: u64, timestamp: u64) -> Self {
46 Self::new(node_addr, node_addr, sequence, timestamp)
47 }
48
49 pub fn with_signature(
51 node_addr: NodeAddr,
52 parent_id: NodeAddr,
53 sequence: u64,
54 timestamp: u64,
55 signature: Signature,
56 ) -> Self {
57 Self {
58 node_addr,
59 parent_id,
60 sequence,
61 timestamp,
62 signature: Some(signature),
63 }
64 }
65
66 pub fn node_addr(&self) -> &NodeAddr {
68 &self.node_addr
69 }
70
71 pub fn parent_id(&self) -> &NodeAddr {
73 &self.parent_id
74 }
75
76 pub fn sequence(&self) -> u64 {
78 self.sequence
79 }
80
81 pub fn timestamp(&self) -> u64 {
83 self.timestamp
84 }
85
86 pub fn signature(&self) -> Option<&Signature> {
88 self.signature.as_ref()
89 }
90
91 pub fn set_signature(&mut self, signature: Signature) {
93 self.signature = Some(signature);
94 }
95
96 pub fn sign(&mut self, identity: &Identity) -> Result<(), TreeError> {
101 if identity.node_addr() != &self.node_addr {
102 return Err(TreeError::InvalidSignature(self.node_addr));
103 }
104 let signature = identity.sign(&self.signing_bytes());
105 self.signature = Some(signature);
106 Ok(())
107 }
108
109 pub fn is_root(&self) -> bool {
111 self.node_addr == self.parent_id
112 }
113
114 pub fn is_signed(&self) -> bool {
116 self.signature.is_some()
117 }
118
119 pub fn signing_bytes(&self) -> Vec<u8> {
123 let mut bytes = Vec::with_capacity(48);
124 bytes.extend_from_slice(self.node_addr.as_bytes());
125 bytes.extend_from_slice(self.parent_id.as_bytes());
126 bytes.extend_from_slice(&self.sequence.to_le_bytes());
127 bytes.extend_from_slice(&self.timestamp.to_le_bytes());
128 bytes
129 }
130
131 pub fn verify(&self, pubkey: &XOnlyPublicKey) -> Result<(), TreeError> {
135 let signature = self
136 .signature
137 .as_ref()
138 .ok_or(TreeError::InvalidSignature(self.node_addr))?;
139
140 let secp = secp256k1::Secp256k1::verification_only();
141 let hash = self.signing_hash();
142
143 secp.verify_schnorr(signature, &hash, pubkey)
144 .map_err(|_| TreeError::InvalidSignature(self.node_addr))
145 }
146
147 fn signing_hash(&self) -> [u8; 32] {
149 use sha2::{Digest, Sha256};
150 let mut hasher = Sha256::new();
151 hasher.update(self.signing_bytes());
152 hasher.finalize().into()
153 }
154
155 pub fn is_fresher_than(&self, other: &ParentDeclaration) -> bool {
157 self.sequence > other.sequence
158 }
159}
160
161impl fmt::Debug for ParentDeclaration {
162 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
163 f.debug_struct("ParentDeclaration")
164 .field("node_addr", &self.node_addr)
165 .field("parent_id", &self.parent_id)
166 .field("sequence", &self.sequence)
167 .field("is_root", &self.is_root())
168 .field("signed", &self.is_signed())
169 .finish()
170 }
171}
172
173impl PartialEq for ParentDeclaration {
174 fn eq(&self, other: &Self) -> bool {
175 self.node_addr == other.node_addr
176 && self.parent_id == other.parent_id
177 && self.sequence == other.sequence
178 && self.timestamp == other.timestamp
179 }
180}
181
182impl Eq for ParentDeclaration {}