defuse_core/engine/
mod.rs1mod inspector;
2mod state;
3
4pub use self::{inspector::*, state::*};
5
6use defuse_crypto::{Payload, SignedPayload};
7
8use crate::{
9 DefuseError, Result,
10 intents::{DefuseIntents, ExecutableIntent},
11 payload::{DefusePayload, ExtractDefusePayload, multi::MultiPayload},
12};
13
14use self::deltas::{Deltas, Transfers};
15
16pub struct Engine<S, I> {
17 pub state: Deltas<S>,
18 pub inspector: I,
19}
20
21impl<S, I> Engine<S, I>
22where
23 S: State,
24 I: Inspector,
25{
26 #[inline]
27 pub fn new(state: S, inspector: I) -> Self {
28 Self {
29 state: Deltas::new(state),
30 inspector,
31 }
32 }
33
34 pub fn execute_signed_intents(
35 mut self,
36 signed: impl IntoIterator<Item = MultiPayload>,
37 ) -> Result<Transfers> {
38 for signed in signed {
39 self.execute_signed_intent(signed)?;
40 }
41 self.finalize()
42 }
43
44 fn execute_signed_intent(&mut self, signed: MultiPayload) -> Result<()> {
45 let public_key = signed.verify().ok_or(DefuseError::InvalidSignature)?;
47
48 let hash = signed.hash();
50
51 let DefusePayload::<DefuseIntents> {
53 signer_id,
54 verifying_contract,
55 deadline,
56 nonce,
57 message: intents,
58 } = signed.extract_defuse_payload()?;
59
60 if verifying_contract != *self.state.verifying_contract() {
62 return Err(DefuseError::WrongVerifyingContract);
63 }
64
65 self.inspector.on_deadline(deadline);
66 if deadline.has_expired() {
68 return Err(DefuseError::DeadlineExpired);
69 }
70
71 if !self.state.has_public_key(&signer_id, &public_key) {
73 return Err(DefuseError::PublicKeyNotExist(signer_id, public_key));
74 }
75
76 self.state.commit_nonce(signer_id.clone(), nonce)?;
78
79 intents.execute_intent(&signer_id, self, hash)?;
80 self.inspector.on_intent_executed(&signer_id, hash);
81
82 Ok(())
83 }
84
85 #[inline]
86 fn finalize(self) -> Result<Transfers> {
87 self.state
88 .finalize()
89 .map_err(DefuseError::InvariantViolated)
90 }
91}