Skip to main content

aura_agent/runtime/effects/
flow.rs

1use super::AuraEffectSystem;
2use async_trait::async_trait;
3use aura_core::effects::{FlowBudgetEffects, JournalEffects};
4use aura_core::types::scope::{AuthorizationOp, ContextOp, ResourceScope};
5use aura_core::{AuraError, AuthorityId, ContextId, FlowCost, FlowNonce, Hash32, ReceiptSig};
6
7// Implementation of FlowBudgetEffects
8#[async_trait]
9impl FlowBudgetEffects for AuraEffectSystem {
10    async fn charge_flow(
11        &self,
12        context: &ContextId,
13        peer: &AuthorityId,
14        cost: FlowCost,
15    ) -> aura_core::AuraResult<aura_core::Receipt> {
16        if let Some((token, bridge)) = &self.journal.journal_policy() {
17            let scope = ResourceScope::Context {
18                context_id: *context,
19                operation: ContextOp::UpdateParams,
20            };
21            let now = self.time_handler.current_timestamp().await?;
22            let decision = bridge
23                .authorize_with_time(token, AuthorizationOp::FlowCharge, &scope, Some(now))
24                .map_err(|e| {
25                    AuraError::permission_denied(format!("flow budget policy failed: {e}"))
26                })?;
27            if !decision.authorized {
28                return Err(AuraError::permission_denied(
29                    "flow budget charge not authorized by Biscuit policy",
30                ));
31            }
32        }
33
34        let budget = JournalEffects::charge_flow_budget(self, context, peer, cost).await?;
35        Ok(aura_core::Receipt::new(
36            *context,
37            self.authority_id,
38            *peer,
39            budget.epoch,
40            cost,
41            FlowNonce::new(budget.spent),
42            Hash32::default(),
43            ReceiptSig::new(Vec::new())?,
44        ))
45    }
46}