keri_controller/identifier/mechanics/
group.rs1use keri_core::{
2 actor::{event_generator, MaterialPath},
3 event::{sections::threshold::SignatureThreshold, KeyEvent},
4 event_message::{
5 cesr_adapter::{parse_event_type, EventType},
6 msg::KeriEvent,
7 signature::{Signature, SignerData},
8 signed_event_message::{Message, Op},
9 EventTypeTag,
10 },
11 mailbox::exchange::{Exchange, ForwardTopic, SignedExchange},
12 prefix::{BasicPrefix, IdentifierPrefix, IndexedSignature, SelfSigningPrefix},
13};
14
15use crate::identifier::Identifier;
16
17use super::MechanicsError;
18
19impl Identifier {
20 pub fn incept_group(
28 &self,
29 participants: Vec<IdentifierPrefix>,
30 signature_threshold: u64,
31 next_keys_threshold: Option<u64>,
32 initial_witness: Option<Vec<BasicPrefix>>,
33 witness_threshold: Option<u64>,
34 delegator: Option<IdentifierPrefix>,
35 ) -> Result<(String, Vec<String>), MechanicsError> {
36 let key_config = self
37 .known_events
38 .storage
39 .get_state(&self.id)
40 .ok_or(MechanicsError::UnknownIdentifierError(self.id.clone()))?
41 .current;
42
43 let mut pks = key_config.public_keys;
44 let mut npks = key_config.next_keys_data.next_keys_hashes();
45 for participant in &participants {
46 let state = self
47 .known_events
48 .storage
49 .get_state(participant)
50 .ok_or(MechanicsError::UnknownIdentifierError(participant.clone()))?;
51 pks.append(&mut state.clone().current.public_keys);
52 npks.append(&mut state.clone().current.next_keys_data.next_keys_hashes());
53 }
54
55 let current_sig_threshold = SignatureThreshold::Simple(signature_threshold);
56 let next_sig_threshold = next_keys_threshold
57 .map(|sig| SignatureThreshold::Simple(sig))
58 .unwrap_or(current_sig_threshold.clone());
59 let icp = event_generator::incept_with_next_hashes(
60 pks,
61 ¤t_sig_threshold,
62 npks,
63 &next_sig_threshold,
64 initial_witness.unwrap_or_default(),
65 witness_threshold.unwrap_or(0),
66 delegator.as_ref(),
67 )?;
68
69 let serialized_icp = String::from_utf8(icp.encode()?)
70 .map_err(|e| MechanicsError::EventGenerationError(e.to_string()))?;
71
72 let mut exchanges = participants
73 .iter()
74 .map(|id| -> Result<_, _> {
75 let exn = event_generator::exchange(id, &icp, ForwardTopic::Multisig).encode()?;
76 String::from_utf8(exn).map_err(|_e| MechanicsError::EventFormatError)
77 })
78 .collect::<Result<Vec<String>, MechanicsError>>()?;
79
80 if let Some(delegator) = delegator {
81 let delegation_request = String::from_utf8(
82 event_generator::exchange(&delegator, &icp, ForwardTopic::Delegate).encode()?,
83 )
84 .map_err(|_e| MechanicsError::EventFormatError)?;
85 exchanges.push(delegation_request);
86 }
87
88 Ok((serialized_icp, exchanges))
89 }
90
91 pub async fn finalize_group_incept(
93 &mut self,
94 group_event: &[u8],
95 sig: SelfSigningPrefix,
96 exchanges: Vec<(Vec<u8>, Signature)>,
97 ) -> Result<IdentifierPrefix, MechanicsError> {
98 let key_event =
100 parse_event_type(group_event).map_err(|_e| MechanicsError::EventFormatError)?;
101 let ke = if let EventType::KeyEvent(icp) = key_event {
102 match icp.event_type {
103 EventTypeTag::Icp | EventTypeTag::Dip => icp,
104 _ => Err(MechanicsError::InceptionError(
105 "Event is not inception".to_string(),
106 ))?,
107 }
108 } else {
109 return Err(MechanicsError::WrongEventTypeError);
110 };
111 let group_prefix = ke.data.get_prefix();
112 self.finalize_event(&ke, sig, exchanges).await?;
113 Ok(group_prefix)
114 }
115
116 pub async fn finalize_group_event(
118 &mut self,
119 group_event: &[u8],
120 sig: SelfSigningPrefix,
121 exchanges: Vec<(Vec<u8>, Signature)>,
122 ) -> Result<(), MechanicsError> {
123 let key_event =
125 parse_event_type(group_event).map_err(|_e| MechanicsError::EventFormatError)?;
126 let ke = if let EventType::KeyEvent(icp) = key_event {
127 icp
128 } else {
129 return Err(MechanicsError::WrongEventTypeError);
130 };
131 self.finalize_event(&ke, sig, exchanges).await?;
132 Ok(())
133 }
134
135 async fn finalize_event(
138 &mut self,
139 key_event: &KeriEvent<KeyEvent>,
140 sig: SelfSigningPrefix,
141 exchanges: Vec<(Vec<u8>, Signature)>,
142 ) -> Result<(), MechanicsError> {
143 let own_index = self.get_index(&key_event.data)?;
144
145 self.known_events
146 .finalize_key_event(&key_event, &sig, own_index)?;
147
148 let signature = IndexedSignature::new_both_same(sig.clone(), own_index as u16);
149
150 let signed_message = key_event.sign(vec![signature], None, None);
151 self.to_notify.push(signed_message);
152
153 let att_signature = IndexedSignature::new_both_same(sig, own_index as u16);
154
155 for (exn, signature) in exchanges {
156 self.finalize_exchange(&exn, signature, att_signature.clone())
157 .await?;
158 }
159 Ok(())
160 }
161
162 pub async fn finalize_exchange(
163 &self,
164 exchange: &[u8],
165 exn_signature: Signature,
166 data_signature: IndexedSignature,
167 ) -> Result<(), MechanicsError> {
168 let material_path = MaterialPath::to_path("-a".into());
170 let parsed_exn =
172 parse_event_type(exchange).map_err(|_e| MechanicsError::EventFormatError)?;
173 if let EventType::Exn(exn) = parsed_exn {
174 let Exchange::Fwd {
175 args: _,
176 to_forward,
177 } = exn.data.data.clone();
178
179 let sigs: Vec<_> = if let Some(receipts) = self.known_events.find_receipt(
180 &to_forward.data.get_prefix(),
181 to_forward.data.get_sn(),
182 &to_forward.digest()?,
183 )? {
184 receipts
185 .signatures
186 .iter()
187 .map(|c| Signature::NonTransferable(c.clone()))
188 .chain([Signature::Transferable(
189 SignerData::JustSignatures,
190 vec![data_signature],
191 )])
192 .collect::<Vec<_>>()
193 } else {
194 vec![Signature::Transferable(
195 SignerData::JustSignatures,
196 vec![data_signature],
197 )]
198 };
199
200 let signer_exn = Message::Op(Op::Exchange(SignedExchange {
201 exchange_message: exn,
202 signature: vec![exn_signature],
203 data_signature: (material_path.clone(), sigs.clone()),
204 }));
205 let wits = self
206 .known_events
207 .get_state_at_event(&to_forward)?
208 .witness_config
209 .witnesses;
210 if let Some(wit) = wits.first() {
212 self.communication
213 .send_message_to(
214 IdentifierPrefix::Basic(wit.clone()),
215 keri_core::oobi::Scheme::Http,
216 signer_exn,
217 )
218 .await?;
219 }
220 Ok(())
221 } else {
222 Ok(())
223 }
224 }
225}