Lease Lifecycle
The states a compute lease moves through
A compute lease passes through three phases: creation, acceptance, and settlement. Each phase produces an on-chain block that the ledger validates.
#Phase 1: Lease creation (consumer)
The consumer creates a lease block on their account chain. This debits XUSD from their balance to pay for the requested resources.
{ "type": "lease", "account": "<consumer pubkey>", "previous": "<frontier hash>", "balance": "<previous XUSD balance - cost>", "asset": "XUSD", "destination": "<provider pubkey>", "amount": "<cost>", "vcpus": 2, "memory_mb": 4096, "disk_gb": 50, "duration": 3600, "access_pub_key": "<ed25519 pubkey hex, 64 chars>"}The block is signed, PoW-solved, and broadcast to the network via gossip.
#What happens on broadcast
The lease block creates a pending send to the provider. The provider's node sees this pending send and -- if configured with -provide -- automatically begins the acceptance flow.
#Phase 2: Lease acceptance (provider)
The provider creates a lease_accept block on their account chain. This stakes XUSD collateral and records timekeeper-attested start time.
{ "type": "lease_accept", "account": "<provider pubkey>", "previous": "<frontier hash>", "balance": "<previous XUSD balance - stake>", "asset": "XUSD", "source": "<lease block hash>", "amount": "<stake>", "certificate_hash": "<performance certificate hash>", "attestations": [...]}#Acceptance steps
- Balance check — verify sufficient XUSD for the stake.
- Resource check — verify available vCPUs, memory, and disk (including resources reserved by in-flight provisions).
- Gather attestations — request signed timestamps from trusted timekeepers (see Attestations). Attestations are mandatory.
- Provision VM — start the virtual machine with the requested resources. This happens before the accept block is committed — if provisioning fails, the lease is not accepted.
- Create block — build the
lease_acceptblock withcertificate_hashreferencing the provider's performance certificate. - Validate certificate — the ledger verifies the certificate exists in the gossip cache, belongs to this provider, and is not expired.
- Broadcast — publish to the network via gossip.
- Send credentials — deliver VM access info to the consumer via direct messaging.
#Lease record
When the ledger processes a valid lease_accept, it creates a Lease record:
| Field | Source |
|---|---|
LeaseHash | Hash of the original lease block |
Consumer | Lease block's account (creator) |
Provider | Lease block's destination |
VCPUs | From the lease block |
MemoryMB | From the lease block |
DiskGB | From the lease block |
Duration | From the lease block (seconds) |
Cost | Lease block's amount (XUSD) |
Stake | lease_accept block's amount (XUSD) |
StartTime | Median attested timestamp (unix nanos) |
AccessPubKey | From the lease block (ed25519 hex, for SSH access) |
CertificateHash | Provider's performance certificate hash |
Settled | false |
#Phase 3: Settlement (provider)
After the lease duration expires, the provider creates a lease_settle block. This earns XE emission and returns the XUSD stake.
{ "type": "lease_settle", "account": "<provider pubkey>", "previous": "<frontier hash>", "balance": "<previous XE balance + emission>", "asset": "XE", "source": "<lease block hash>", "amount": "<XE emission>", "attestations": [ { "public_key": "<timekeeper pubkey hex>", "timestamp": 1709658000000000000, "signature": "<attestation signature hex>" } ]}#Settlement steps
- Check expiry — the
settleLoop()goroutine checks every 10 seconds whethernow >= startTime + duration. - Gather attestations — request signed timestamps for the settle time. Attestations are mandatory.
- Validate duration — the ledger verifies that
attested_settleTime - startTime >= duration(in nanoseconds). Self-reported timestamps are not accepted. - Create block — build the
lease_settleblock with XE emission. - Broadcast — publish to the network.
- Teardown VM — synchronously stop and clean up the virtual machine (not fire-and-forget).
- Return stake — the XUSD stake is returned to the provider's balance.
- Orphan cleanup — the settle loop also cleans up any VMs whose leases are settled but teardown failed.
#Duration limits
| Limit | Value | Human |
|---|---|---|
| Minimum | 60 seconds | 1 minute |
| Maximum | 31,536,000 seconds | 365 days |
The ledger rejects lease blocks with durations outside this range.
#Automatic settlement
The provider node runs a background settleLoop() goroutine that:
- Ticks every 10 seconds.
- Queries all leases where this node is the provider.
- Skips leases already settled.
- For each expired lease (
now >= startTime + duration), callssettleLease(). settleLease()gathers attestations, creates thelease_settleblock, and tears down the VM.
#Lease struct
The Lease struct tracks the full state of an active or settled lease:
type Lease struct { LeaseHash string // hash of the lease block Consumer string // consumer account (lease block creator) Provider string // provider account (lease block destination) VCPUs uint64 MemoryMB uint64 DiskGB uint64 Duration uint64 // seconds AccessPubKey string // ed25519 pubkey hex for SSH access Cost uint64 // XUSD paid by consumer Stake uint64 // XUSD staked by provider StartTime int64 // unix nanos (median attested timestamp) CertificateHash string // provider's performance certificate Settled bool}#Sequence diagram
Consumer Node Network Provider Node │ │ │ │ create lease block │ │ │ (debit XUSD) │ │ │ ─────────────────────────►│ │ │ │ gossip lease block │ │ │──────────────────────────►│ │ │ │ detect pending send │ │ │ check resources available │ │ │ gather start attestations │ │ │ provision VM (before accept!) │ │ │ create lease_accept │ │ gossip lease_accept │ (stake XUSD + cert hash) │ │◄──────────────────────────│ │ receive VM credentials │ │ send credentials │◄──────────────────────────│───────────────────────────│ │ │ │ │ ... lease duration elapses ... │ │ │ │ │ │ │ settleLoop detects expiry │ │ │ gather settle attestations │ │ │ create lease_settle │ │ gossip lease_settle │ (earn XE, recover stake) │ │◄──────────────────────────│ │ │ │ teardown VM (synchronous)