defuse_core/engine/
mod.rsmod inspector;
mod state;
pub use self::{inspector::*, state::*};
use defuse_crypto::{Payload, SignedPayload};
use crate::{
DefuseError, Result,
intents::{DefuseIntents, ExecutableIntent},
payload::{DefusePayload, ExtractDefusePayload, multi::MultiPayload},
};
use self::deltas::{Deltas, Transfers};
pub struct Engine<S, I> {
pub state: Deltas<S>,
pub inspector: I,
}
impl<S, I> Engine<S, I>
where
S: State,
I: Inspector,
{
#[inline]
pub fn new(state: S, inspector: I) -> Self {
Self {
state: Deltas::new(state),
inspector,
}
}
pub fn execute_signed_intents(
mut self,
signed: impl IntoIterator<Item = MultiPayload>,
) -> Result<Transfers> {
for signed in signed {
self.execute_signed_intent(signed)?;
}
self.finalize()
}
fn execute_signed_intent(&mut self, signed: MultiPayload) -> Result<()> {
let public_key = signed.verify().ok_or(DefuseError::InvalidSignature)?;
let hash = signed.hash();
let DefusePayload::<DefuseIntents> {
signer_id,
verifying_contract,
deadline,
nonce,
message: intents,
} = signed.extract_defuse_payload()?;
if verifying_contract != *self.state.verifying_contract() {
return Err(DefuseError::WrongVerifyingContract);
}
self.inspector.on_deadline(deadline);
if deadline.has_expired() {
return Err(DefuseError::DeadlineExpired);
}
if !self.state.has_public_key(&signer_id, &public_key) {
return Err(DefuseError::PublicKeyNotExist);
}
if !self.state.commit_nonce(signer_id.clone(), nonce) {
return Err(DefuseError::NonceUsed);
}
intents.execute_intent(&signer_id, self, hash)?;
self.inspector.on_intent_executed(&signer_id, hash);
Ok(())
}
#[inline]
fn finalize(self) -> Result<Transfers> {
self.state
.finalize()
.map_err(DefuseError::InvariantViolated)
}
}