SLA Lifecycle
SLASettle enforces a deterministic, state-machine-driven lifecycle for all service level agreements.
State Transitions
The core agreement status is defined by the SLAStatus enum in sla_vault:
rust
#[contracttype]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum SLAStatus {
Active = 1,
Cancelled = 2,
}text
+-------------------------------------------------------------+
| |
| Provider calls create_sla() |
| - Escrows initial bond |
| - Configures quorum, penalty, and beneficiary |
v |
+--------------+ |
| Active | <------------------------------------+ |
+--------------+ | |
| | |
| Per-Round Monitoring: | |
| - Watchers probe endpoint | |
| - submit_check(UP/DOWN) | Top Up Bond: |
| | provider adds|
| If votes_down >= quorum_threshold: | funds |
| - trigger_settlement() | |
| - Penalty paid to beneficiary | |
| - Bond balance decremented | |
| | |
+----------------------------------------------+ |
| |
| Provider calls cancel_sla() |
v |
+--------------+ |
| Cancelled | |
+--------------+ |
| |
| Provider calls withdraw_remaining_bond() |
v |
+--------------------------+ |
| Collateral Returned to | |
| Provider Wallet (Closed) | |
+--------------------------+ |Detailed Lifecycle Steps
1. Agreement Creation (create_sla)
- Caller: Service Provider (
provider.require_auth()). - Collateral Transfer: Transfers
bond_amountoftokenfrom provider tosla_vaultvia the Stellar Asset Contract interface. - Initialization: Assigns a monotonic
sla_id(from instance keyNextSlaId), sets initial bond balance, stores SLA parameters in persistent storage, and assigns statusActive. - Event: Emits
SlaCreated { sla_id, provider, token, bond_amount, beneficiary }.
2. Round Health Attestation
- Each round (identified by an incremental
round_id), registered watchers independently execute HTTP health checks against the target endpoint. - Watchers call
watcher_registry.submit_check(watcher, sla_id, round_id, endpoint_hash, status). - The registry increments
votes_uporvotes_downin the round'sRoundTallyrecord and marksDataKey::Check(sla_id, round_id, watcher)to prevent duplicate submissions.
3. Settlement Execution (trigger_settlement)
- When downtime occurs and
votes_down >= quorum_threshold: - Any caller (beneficiary, keeper, or public observer) invokes
sla_vault.trigger_settlement(caller, sla_id, round_id). - Validation Pipeline:
- Verifies agreement is
Active(SlaNotActiveif cancelled). - Checks idempotency: confirms the round has not already been settled (
AlreadySettled). - Queries
watcher_registry.get_round_tally(sla_id, round_id). - Verifies
tally.votes_down >= config.quorum_threshold(QuorumNotMetif false). - Determines payout:
payout = min(config.penalty_per_breach, current_bond_balance). If balance is 0, rejects withBondExhausted. - Executes transfer from vault to
beneficiary. - Decrements bond balance and marks
DataKey::SettledRounds(sla_id, round_id) = true. - Emits
SettlementPaid { sla_id, round_id, payout, beneficiary }.
- Verifies agreement is
4. Bond Top-Up (top_up_bond)
- As penalties deplete the escrow, the original provider can replenish collateral by calling
top_up_bond(caller, sla_id, amount). - The vault transfers tokens into escrow and extends persistent storage TTLs.
- Emits
BondToppedUp { sla_id, amount }.
5. Agreement Cancellation (cancel_sla)
- To conclude service or decommission an agreement, the provider calls
cancel_sla(caller, sla_id). - Sets status to
Cancelled. - Irreversibility: Cancellation is one-way. An SLA cannot be un-cancelled.
- Emits
SlaCancelled { sla_id }.
6. Bond Withdrawal (withdraw_remaining_bond)
- Once cancelled, the provider calls
withdraw_remaining_bond(caller, sla_id). - The contract confirms the SLA is
Cancelled, ensures remaining balance is positive, transfers all remaining tokens to the provider, sets the balance to 0, and emitsBondWithdrawn. - Escrow funds cannot be quietly drained while the SLA remains active.