Skip to main content

Overview

Cowboy introduces five fundamental innovations that enable autonomous agents and verifiable computation at the protocol level. Each addresses a critical limitation in existing blockchain platforms.
Note: Code examples show the real cowboy_sdk (CIP-6) and pvm_host APIs. See SDK Overview for the full surface.

Native Timers

Protocol-level scheduling with O(1) enqueue

Dual-Metered Gas

Independent pricing for compute and storage

Python Smart Contracts

Deterministic Rust-based PVM for a high-level language

Verifiable Off-Chain

Decentralized LLM/HTTP/MCP compute with proofs

Encrypted Storage (CBFS)

Distributed erasure-coded filesystem with FUSE mount

1. Native Protocol Timers

The Problem

Traditional blockchains have no concept of time-based execution:
// ❌ Ethereum: This function never executes itself
contract Liquidator {
    function checkPosition() public {
        if (position.isUndercollateralized()) {
            liquidate();
        }
        // Who calls this function? When?
    }
}
Current workarounds:
  • Cron jobs: Centralized, single point of failure
  • Keeper networks: Expensive, complex to integrate
  • User triggers: Poor UX, unreliable

Cowboy’s Solution: Hierarchical Calendar Queue

A three-tiered scheduling system built into the consensus layer:
+--------------------------------------------------------------------+
|  Layer 3: Overflow Sorted Set (long-term)                          |
|  - Merkleized balanced BST                                         |
|  - For distant future timers                                       |
+-------------------------------+------------------------------------+
                                | Promote timers as they enter range
                                v
+--------------------------------------------------------------------+
|  Layer 2: Epoch Queue (mid-term)                                   |
|  - Array of epoch buckets (e.g., hourly epochs)                    |
|  - Amortized promotion cost                                        |
+-------------------------------+------------------------------------+
                                | Promote timers as epoch approaches
                                v
+--------------------------------------------------------------------+
|  Layer 1: Block Ring Buffer (near-term)                            |
|  - Fixed-size array (e.g., 256 blocks)                             |
|  - O(1) enqueue and dequeue                                        |
|  - Bucket per block height                                         |
+--------------------------------------------------------------------+
Key properties:
  • O(1) scheduling: Constant-time enqueue for near-term timers
  • Scalable: Handles millions of timers efficiently
  • Deterministic: Part of consensus state
  • Fair: Gas bidding prevents DoS

Dynamic Gas Bidding

Actors compete for timer execution during congestion (CIP-1):
  • Schedule a timer referencing a designated Gas Bidding Agent (GBA).
  • When due, the producer queries the GBA with protocol context to obtain fee params.
  • Timers are prioritized by effective tip within a fixed per-block processing budget.
// CIP-1: Standard GBA interface (normative)
interface GasBiddingAgent {
  function getGasBid(bytes calldata context) external view returns (TxFeeParams);
}
Context provided to GBA: Context provided to GBA (CIP-1):
  • trigger_block_height — originally scheduled height
  • current_block_height — current height (for delay)
  • basefee_cycle — current cycle basefee
  • basefee_cell — current cell basefee
  • last_block_cycle_usage — congestion indicator
  • owner_actor_balance — actor’s current CBY balance
Benefits:
  • Actors self-prioritize based on urgency
  • Market-driven resource allocation
  • DeFi liquidations can bid high during volatility
  • Non-critical tasks bid low during congestion

DoS Protection

Fixed per-block budget prevents abuse:
# Protocol constants
TIMER_PROCESSING_BUDGET_CYCLES = 10_000_000  # Example value per block
RING_BUFFER_SIZE = 256  # Example ring buffer size
EPOCH_SIZE = 360  # Example epoch blocks (~1 hour)
How it works:
  1. At each block, timers sorted by effective tip
  2. Execute highest-priority timers first
  3. Stop when budget exhausted
  4. Unexecuted timers roll over to next block
Result: Regular transactions always have guaranteed block space.

2. Dual-Metered Gas Model

The Problem

Single gas metrics are fundamentally unfair:
# Scenario A: Heavy compute, small storage
def verify_proof(proof):  # 100,000 gas
    # Complex cryptography
    return is_valid

# Scenario B: Light compute, large storage  
def store_blob(data):  # 100,000 gas
    storage[key] = data  # 10 KB

# Problem: Both cost the same, but have different resource impacts!
Real-world impacts:
  • Storage-heavy apps subsidized by compute-heavy apps
  • Unpredictable costs (gas depends on market, not actual usage)
  • Incentive misalignment (storage should cost more long-term)

Cowboy’s Solution: Cycles + Cells

Two independent dimensions with separate fee markets:
What it measures: CPU workMetering method: Instruction-level trackingExamples:
# Arithmetic: 1 cycle
x = a + b

# Function call: 10 cycles  
result = foo(x)

# Dictionary access: 3 cycles
value = my_dict[key]

# Cryptography: 3,000 cycles
verify_ecdsa(msg, sig, pubkey)

# String operation: 1 cycle per character
result = "hello" + "world"  # 10 cycles
See: Fee Model Overview

Independent Fee Markets

Each resource has its own EIP-1559 style basefee:
# Cycle market
basefee_cycle_new = basefee_cycle_old × (1 + (U_c - T_c) / T_c / α)

# Cell market  
basefee_cell_new = basefee_cell_old × (1 + (U_b - T_b) / T_b / α)

# Where:
# U = actual usage in parent block
# T = target usage (typically 50% of limit)
# α = adjustment speed (e.g., 8)
Benefits:
  • Each resource priced based on its own demand
  • Compute-heavy apps don’t affect storage prices
  • Storage bloat doesn’t affect compute prices
  • Fair for all use cases

Example: Fair Pricing in Action

# App A: AI inference (high compute, low storage)
def run_model(input_data):
    result = heavy_computation(input_data)  # 50,000 Cycles
    self.storage.set("result", result)      # 100 Cells
    return result

# Cost: 50,000 × basefee_c + 100 × basefee_b
# Mostly pays for compute ✅

# App B: Data marketplace (low compute, high storage)
def store_dataset(dataset):
    self.storage.set("data", dataset)  # 1,000,000 Cells
    return "stored"                     # 500 Cycles

# Cost: 500 × basefee_c + 1,000,000 × basefee_b  
# Mostly pays for storage ✅

3. Deterministic Python VM

The Problem

Smart contract languages are niche and difficult:
// Solidity: Steep learning curve
contract Counter {
    uint256 private count;
    
    function increment() public {
        count += 1;
    }
}
Challenges:
  • New language to learn
  • Limited tooling and libraries
  • Difficult to express complex logic
  • Small developer community

Cowboy’s Solution: Python with Determinism

Actors are real Python. Here’s the scaffolded hello actor using the low-level PVM host API:
# actors/hello/main.py
class Actor:
    """A Cowboy actor deployed on-chain."""

    def __init__(self):
        self.counter = 0

    def increment(self):
        self.counter += 1
        return self.counter

    def get_count(self):
        return self.counter
And the same thing using the CIP-6 cowboy_sdk:
from cowboy_sdk import actor

@actor
class Counter:
    def __init__(self):
        self.storage["count"] = 0

    def increment(self):
        self.storage["count"] += 1
        return self.storage["count"]

Achieving Determinism

Challenge: Python is inherently non-deterministic (dict ordering, floats, GC, etc.) Cowboy’s approach: Constrained deterministic subset
All floating-point operations use deterministic software implementation.
# ✅ Deterministic across all hardware
x = 3.14159 * 2.71828  # Software math library

# ❌ Hardware FPU (non-deterministic)
Only a curated stdlib subset is available.
# ✅ Allowed
import math           # Deterministic software impl
import hashlib        # Deterministic hashing
import json
import pvm_host       # Low-level host API
from cowboy_sdk import actor, runner  # CIP-6 SDK

# ❌ Prohibited
import os             # System calls
import requests       # Network I/O
import random         # Non-deterministic (use protocol VRF)
import time           # Non-deterministic (use ctx block time)
Reference counting + no cycle detection during execution.
# Memory management is immediate and deterministic
obj = [1, 2, 3]  # Allocate: charged Cells
del obj           # Deallocate: charged Cycles
Pure interpretation mode only.
  • Ensures identical execution across nodes
  • Predictable gas costs
  • No non-deterministic optimization
No concurrency, no race conditions.
# ✅ Single message at a time
def handle_message(self, msg):
    # No concurrent access to self.state
    self.state += 1

# ❌ No threads, no asyncio.gather(), etc.

Sandboxing

The VM enforces strict isolation:
  • ✅ Allowed (conceptual): persistent storage via host functions; actor messaging; timer scheduling; deterministic hashing.
  • ❌ Prohibited: file I/O, network access, system calls, non-deterministic randomness.

Resource Metering

Every operation has a precise cost:
# Operation costs (examples)
x = 1 + 2                    # 1 Cycle
foo()                        # 10 Cycles (call)
"hello" + "world"            # base + per-char surcharge
[x for x in range(1000)]     # 40 + 2000 + ... Cycles
verify_ecdsa(msg, sig, pk)   # 3000 Cycles
See also: Fee Model Metering Points

4. Verifiable Off-Chain Compute

The Problem

On-chain computation is expensive and limited:
# ❌ Can't do this on-chain
def analyze_sentiment(text):
    model = load_model("bert-large")  # 500 MB model
    return model.predict(text)        # 1B+ operations

# ❌ Can't do this on-chain  
def fetch_price():
    response = requests.get("https://api.coingecko.com/...")
    return response.json()
But off-chain introduces trust issues!

Cowboy’s Solution: Decentralized Runner Network

Outsource computation to a marketplace of runners with verifiable results (CIP-2):
  • Submit a task to the Dispatcher with a mandatory result_schema and payment terms.
  • Runners self-select via VRF-based logic and either execute or skip deterministically.
  • Results and (optional) proofs are submitted on-chain; when N results are collected, a deferred callback is triggered.
  • The Actor consumes a chosen result and finalizes payment distribution.

VRF-Based Runner Selection

No centralized scheduler required:
# Deterministic, verifiable selection
start_index = hash(vrf_seed + (submission_block - vrf_generation_block)) % list_size
selected_runners = active_runner_list[start_index : start_index + N]
Properties:
  • ✅ Decentralized: No single coordinator
  • ✅ Verifiable: Anyone can check selection validity
  • ✅ Unpredictable: Can’t game the system
  • ✅ Fair: All runners have equal probability

Runner Lifecycle

+--------------------------------------------------------------------+
|  1. Task Submission                                                |
|  Developer submits task + schema + payment                         |
+-------------------------------+------------------------------------+
                                |
                                v
+--------------------------------------------------------------------+
|  2. VRF Selection                                                  |
|  Deterministic runner assignment                                   |
+-------------------------------+------------------------------------+
                                |
                                v
+--------------------------------------------------------------------+
|  3. Off-Chain Execution                                            |
|  Selected runners execute task                                     |
|  - Download data/models                                            |
|  - Run computation                                                 |
|  - Generate proof (if required)                                    |
+-------------------------------+------------------------------------+
                                |
                                v
+--------------------------------------------------------------------+
|  4. Result Submission                                              |
|  Runners submit results + proofs on-chain                          |
+-------------------------------+------------------------------------+
                                |
                                v
+--------------------------------------------------------------------+
|  5. Deferred Callback                                              |
|  When N results collected, callback triggered                      |
+-------------------------------+------------------------------------+
                                |
                                v
+--------------------------------------------------------------------+
|  6. Payment Distribution                                           |
|  Actor chooses winning result, runner gets paid                    |
+--------------------------------------------------------------------+

Flexible Verification

Choose the proof type based on your requirements:
Use case: General computation with economic security
  • Configure N runners; accept when ≥ quorum match.
  • Pros: Simple, broad applicability
  • Cons: Pay multiple runners

Economic Model

Market-driven pricing, not protocol gas:
# Runners self-price based on:
# • Compute time
# • Memory usage  
# • Model download costs
# • Hardware costs (TEE premium)
# • Desired profit margin

# Actors choose based on:
# • Task urgency
# • Required proof type
# • Budget constraints
Result: Efficient market where actors pay fair prices for actual resources consumed.

5. Encrypted Distributed Storage (CBFS)

The Problem

On-chain state storage is expensive and bounded. Anything large — model weights, datasets, media, logs — needs to live elsewhere:
  • Self-hosted S3 — centralized, single trust anchor
  • IPFS — public content-addressed, no encryption, unreliable pinning
  • Arweave / Filecoin — either unencrypted or require bridging ceremony
None of these integrate cleanly with an actor/runner trust model where short-lived workloads need delegated access to a volume.

Cowboy’s Solution: CBFS

A distributed filesystem where:
  • Data is encrypted client-side with AES-256-GCM before it ever leaves the writer
  • Shards are erasure-codedK data + M parity Reed-Solomon, recover from any K
  • Transport is QUIC — low-latency parallel shard transfers
  • Auth is delegated — owners sign short-lived capability tokens for runners and actors to mount volumes, so the data path does not require a chain write per I/O
  • Mount is FUSE — actors and runners see normal filesystem semantics

Architecture

Writer                                        Storage Relays
──────                                        ──────────────
file → cbfs-fuse (cache)                      cbfs-node × N
       ↓                                      (Sled blob store)
    AES-256-GCM
       ↓                                      Any K shards →
Reed-Solomon (K + M) ── QUIC transport ──→    reconstruct file

Manifest (Merkle tree)

Cowboy chain (volume registry, capability tokens — control plane only)

Key Properties

  • Confidentiality: relays never see plaintext
  • Durability: any K of K + M shards reconstruct the file
  • Self-healing: background repair detects dead nodes and re-shards
  • Chain-light data path: owners sign tokens, relays verify — no chain write per shard read/write
  • Composable with runners: a runner job can mount an input volume and write to an output volume via delegated tokens
See: CIP-4 State Storage · CIP-9 Runner Storage

How They Work Together

These four innovations combine to enable powerful use cases:

Example: Autonomous DeFi Liquidation Bot

Steps (illustrative):
  1. Submit an off-chain task to fetch prices (CIP-2 runner, HTTP executor)
  2. Process results in a @runner.continuation resume handler (compute → cycles)
  3. Persist positions and audit logs (small → state cells, large → CBFS)
  4. Schedule the next check via a CIP-1 timer with a GBA
Uses all five innovations:
  1. Native Timers: self-schedules every N blocks with dynamic bidding
  2. Dual Gas: pays fairly for compute vs. storage
  3. Python VM: expresses complex logic naturally
  4. Off-Chain: fetches external price data via HTTP runner
  5. CBFS: archives historical audit trails off-chain, encrypted

Next Steps

Architecture Deep Dive

Understand the complete system design

Actor VM

Learn how the Python VM achieves determinism

Fee Model

Deep dive into Cycles and Cells metering

Scheduler

Read the timer and bidding overview

Further Reading