Skip to main content

L{CORE} Architecture Decision Records

L{CORE} Specific: These ADRs document L{CORE}'s architectural decisions for IoT attestation. The attestor container uses Reclaim Protocol's attestor-core—decisions about the attestor's internal architecture are Reclaim's. Our decisions focus on how we integrate their infrastructure with Cartesi and IoT devices.

This document records the key architectural decisions made in L{CORE} and the reasoning behind them.

ADR-001: Two-Container Architecture

Status

Accepted

Context

L{CORE} needs both external API capabilities (network access to Reclaim Protocol, database connections) and deterministic on-chain computation (Cartesi rollup). These requirements are fundamentally at odds:

  • External I/O is inherently non-deterministic (network latency, API responses vary)
  • Cartesi rollups require bit-for-bit identical execution across all nodes

Decision

Split the system into two containers:

  1. Attestor Container: Handles all external I/O

    • REST API server
    • Reclaim Protocol integration
    • Supabase database connection
    • Blockchain transaction submission
  2. Cartesi Node Container: Handles deterministic computation

    • Cartesi rollup runtime
    • SQLite state database
    • L{CORE} business logic
    • Inspect/Advance APIs
graph LR
subgraph "Attestor (Non-Deterministic)"
API[REST API]
RECLAIM[Reclaim SDK]
DB[(Supabase)]
TX[TX Submitter]
end

subgraph "Cartesi Node (Deterministic)"
ROLLUP[Rollup Runtime]
SQLITE[(SQLite)]
LCORE[L\{CORE\} Logic]
end

API --> RECLAIM
API --> DB
API --> TX
TX --> ROLLUP
ROLLUP --> SQLITE
SQLITE --> LCORE

Consequences

Positive:

  • Clear separation of concerns
  • Each container can be scaled independently
  • Cartesi VM remains fully deterministic
  • External failures don't affect rollup state

Negative:

  • Inter-container communication adds latency
  • More complex deployment (two images, two deployments)
  • Must coordinate versions between containers

Alternatives Considered

  1. Single Container: Would violate Cartesi's determinism requirements
  2. Sidecar Pattern: Similar complexity but less clear separation
  3. Lambda/Serverless for Attestor: Higher latency, cold start issues

ADR-002: Cartesi for On-Chain State

Status

Accepted

Context

Need to store and query attestation data with:

  • Complex access control (grants, revocations, time-based)
  • Rich queries (filter by provider, date range, data type)
  • Privacy (encrypted fields, selective disclosure)
  • On-chain verifiability

Decision

Use Cartesi rollup with SQLite for state management.

graph TB
subgraph "Traditional Smart Contract"
SC[Solidity Contract]
MAP1[mapping address => data]
MAP2[mapping bytes32 => grant]
end

subgraph "Cartesi Rollup"
VM[Linux VM]
SQL[(SQLite)]
QUERY[Complex SQL Queries]
JOIN[JOINs, Aggregations]
end

SC --> |Limited| MAP1 & MAP2
VM --> SQL --> QUERY --> JOIN

Consequences

Positive:

  • Full SQL query support (JOINs, aggregations, window functions)
  • Complex access control logic possible
  • Cryptographically verifiable state (fraud proofs)
  • Run any Linux binary for data processing

Negative:

  • Requires Cartesi-specific deployment infrastructure
  • Learning curve for Cartesi development
  • Finality depends on fraud proof window

Alternatives Considered

  1. Pure Solidity: Limited query capabilities, expensive storage (~20k gas per 32 bytes)
  2. Standard Optimistic Rollup: Good but no Linux environment for complex data processing
  3. zkRollup: Expensive proof generation for complex queries
  4. Off-chain Database: No verifiability, trust assumptions

ADR-003: Reclaim Protocol for Data Verification

Status

Accepted

Context

Need to verify user data from arbitrary web sources:

  • Banking APIs (account balances, transaction history)
  • Social media (followers, posts, verification status)
  • Commerce platforms (purchase history, ratings)
  • Government services (identity, licenses)

Verification must be:

  • Privacy-preserving (don't expose raw data)
  • Decentralized (no central authority)
  • User-controlled (user initiates proof generation)

Decision

Use Reclaim Protocol's zkTLS proofs for data attestation.

sequenceDiagram
participant User
participant Browser
participant API as External API
participant Reclaim as Reclaim Network
participant Attestor as L\{CORE\} Attestor

User->>Browser: Initiate proof request
Browser->>API: HTTPS request
API-->>Browser: TLS response
Browser->>Reclaim: Submit TLS transcript
Reclaim->>Reclaim: Generate zkTLS proof
Reclaim-->>Browser: Proof + signature
Browser->>Attestor: Submit proof
Attestor->>Attestor: Verify proof
Attestor-->>User: Attestation stored

Consequences

Positive:

  • Any HTTPS data source can be verified
  • User privacy preserved (zero-knowledge proofs)
  • Decentralized verification (Reclaim network)
  • No API keys or partnerships needed with data sources

Negative:

  • Requires Reclaim SDK integration
  • Proof generation happens on user's device (mobile/browser)
  • Limited to HTTPS sources (no native app data)

Alternatives Considered

  1. Direct API Integration: Requires partnerships, API keys, trust
  2. TEE-only Verification: No ZK privacy, larger trusted compute base
  3. Custom zkTLS: Massive engineering effort, unproven security

ADR-004: EigenCloud for TEE Deployment

Status

Accepted

Context

Need a Trusted Execution Environment (TEE) for:

  • Hardware-backed isolation of attestation logic
  • Verifiable execution (attestation reports)
  • Protection of signing keys
  • Compliance requirements

Decision

Deploy to EigenCloud's managed TEE infrastructure.

Consequences

Positive:

  • Hardware-level security (Intel SGX/TDX)
  • Managed infrastructure (no K8s expertise needed)
  • Pay-per-compute pricing
  • Built-in attestation support

Negative:

  • Vendor dependency on EigenCloud
  • Limited to supported regions
  • Must adapt to EigenCloud's deployment model

Alternatives Considered

  1. Self-hosted SGX: Complex setup, hardware procurement, maintenance
  2. AWS Nitro Enclaves: Good but more expensive, AWS lock-in
  3. Azure Confidential Computing: Similar to AWS, Azure lock-in
  4. No TEE: Unacceptable security tradeoff for attestation

ADR-005: Arbitrum Sepolia for Settlement

Status

Accepted

Context

Need a blockchain for:

  • Cartesi InputBox contract deployment
  • Settlement of attestations
  • Access control enforcement
  • Immutable audit trail

Decision

Use Arbitrum Sepolia (testnet) with planned migration to Arbitrum One (mainnet).

Consequences

Positive:

  • Low gas costs (L2 scaling)
  • Fast finality (~1 second)
  • EVM compatibility (existing tools work)
  • Strong ecosystem and bridge support

Negative:

  • Testnet (Sepolia) is not production-grade
  • Sequencer centralization risk
  • Must migrate to mainnet for production

Alternatives Considered

  1. Ethereum Mainnet: Too expensive for frequent attestations
  2. Custom Appchain: Overkill for current scale, fragmented liquidity
  3. Other L2s: Less ecosystem support for Cartesi integration

ADR-006: URL-Encoded JSON for Inspect Queries

Status

Accepted

Context

Cartesi's inspect endpoint accepts payloads in the URL path. Need to determine encoding format.

Decision

Use URL-encoded JSON (encodeURIComponent(JSON.stringify(query))).

Correct:

const query = { type: 'all_provider_schemas', params: {} }
const url = `/inspect/${encodeURIComponent(JSON.stringify(query))}`

Wrong (hex encoding):

const payload = '0x' + Buffer.from(JSON.stringify(query)).toString('hex')
const url = `/inspect/${payload}`

Consequences

Positive:

  • Human-readable in logs and debugging
  • Standard URL encoding, widely supported
  • Easy to construct in any language

Negative:

  • Longer URLs for large queries
  • Must remember to use encodeURIComponent, not hex

Rationale

The Cartesi node's inspect handler expects the raw JSON string in the path, which it then parses. Hex encoding the payload causes the handler to receive a hex string instead of JSON, resulting in "Unknown query type" errors.