Status: Draft for Internal Review
Type: Standards Track
Category: Core
Created: 2025-10-01
Type: Standards Track
Category: Core
Created: 2025-10-01
Cowboy Improvement Proposal (CIP-1): The Autonomous Actor Scheduler
Status: Draft for internal review Type: Standards Track Category: CoreAbstract
This document specifies the design of the Autonomous Actor Scheduler, the protocol-level mechanism responsible for implementing chain-native timers. It combines two key technologies: a tiered Calendar Queue for scalable, O(1) event scheduling, and an autonomous gas bidding model for execution. When a timer is due, the protocol queries a user-defined Gas Bidding Agent (GBA) contract, providing it with real-time block context. The GBA’s returned bid determines the timer’s priority within a dedicated processing budget for that block. This design enables truly autonomous actors that can dynamically respond to network congestion and weigh the urgency of their own scheduled tasks.1. Motivation
The Cowboy actor model’s reliance on timers requires a scheduler that is not only scalable but also intelligent. Network conditions are dynamic, and the importance of a scheduled task can change based on external events. A fixed, pre-paid gas fee for a future transaction is insufficient. This design allows actors to make real-time, economically rational decisions about the cost of their own execution, ensuring that high-priority tasks can aggressively compete for block space when it matters most.2. The Tiered Calendar Queue Design
The Actor Scheduler state is part of the global consensus state (σ) and is organized into a three-tier structure to efficiently manage timers across different time horizons.
2.1 Tier 1: The Block Ring Buffer
This tier handles imminent timers scheduled for the near future.- Structure: A fixed-size array (or “ring buffer”) of buckets, where each bucket corresponds to a single block height. Let’s call this size
RING_BUFFER_SIZE. - Function: When an actor schedules a timer for block
H, the message is placed into bucketH % RING_BUFFER_SIZE. - Performance: Enqueue and dequeue operations are
O(1), as the block producer only needs to access the single bucket corresponding to the current block height.
2.2 Tier 2: The Epoch Queue
This tier manages timers scheduled for the medium-term future, beyond the scope of the Ring Buffer.- Structure: An array of buckets, where each bucket corresponds to a future epoch (e.g., one hour of blocks ).
- Function: A timer scheduled for a block in epoch
Eis placed into the bucket for epochE. At the beginning of each new epoch, a protocol-level maintenance operation redistributes all timers from that epoch’s bucket into the appropriate slots in the Block Ring Buffer. This redistribution work is an amortized cost.
2.3 Tier 3: The Overflow Sorted Set
This tier is a catch-all for very long-term timers that fall outside the Epoch Queue’s range.- Structure: A Merkleized Balanced Binary Search Tree, ordered by block height.
- Function: Timers scheduled far in the future are inserted here. During epoch maintenance, the protocol also checks this tree for any timers that now fall within the Epoch Queue’s range and migrates them accordingly.
3. Integration with the State Transition Function
The introduction of autonomous bidding modifies the state transition function to include a contextual query step. Let σ be the global state, B a block with transactions T_i, basefees (bf_c, bf_b), and randomness R.- Header/Proposer: Determined by HotStuff and the previous QC.
- Epoch Maintenance (if applicable): Redistribute timers from higher-tier queues into the Block Ring Buffer.
- Deliver Timers & Build Priority Queue :
a. Access the timer bucket for height(B).
b. For each due timer message, the block producer performs a read-only call to the owner actor’s designated Gas Bidding Agent (GBA), invoking getGasBid(context). The context object is supplied by the protocol (see §4.2).
c. The GBA returns a bid (max_fee_per_cycle, tip_per_cycle, etc.).
d. The producer populates a temporary priority queue with all due timers, ordered by their effective tip. - Execute Prioritized Timers:
a. The producer executes timer-triggered messages from the front of the priority queue.
b. Execution continues until either the queue is empty or the cumulative cycles used exceed the TIMER_PROCESSING_BUDGET_CYCLES for the block. - Priority Weight for the next epoch:
a. For each actor with due timers, compute a normalized priority score S from: effective tip (post-GBA), execution outcome (success/defer), deadline lateness, and per-block budget consumption ratio.
b. Update per-actor weight using exponential decay: weight’ = (1 − λ) · weight + λ · S, where λ is governance-tunable (e.g., 0.2).
c. Enforce bounds and fairness: clamp to [weight_min, weight_max]; apply a starvation floor for actors whose timers were repeatedly deferred; decay weights on inactivity.
d. Application in next epoch: (i) break ties among equal effective tips; (ii) apportion TIMER_PROCESSING_BUDGET_CYCLES slices per actor to smooth congestion while preserving price signals.
e. Persistence & timing: persist weights in σ; recompute on epoch rollover; governance MAY reset or rescale weights when parameters change. - Execute Transactions : Process the ordered transaction set T_i. Actor calls to set_timeout now MUST include the address of the GBA that will manage the timer’s future execution.
- Resolve Jobs, Adjust Basefees, Mint Rewards: These steps proceed as previously defined.
4. Autonomous Bidding and Contextual Execution
4.1 Metering and Economics
- Scheduling Cost: An actor pays a small, fixed cycle cost upfront to call set_timeout and place a timer in the queue.
- Execution Cost: The fee for the eventual execution is determined by the GBA’s dynamic bid. This fee is deducted from the owning actor’s main balance at the time of execution. If the actor’s balance is insufficient to cover the bid returned by its GBA, the timer execution fails for that block and is deferred.
4.2 The Gas Bidding Agent (GBA) and Context
Every actor that schedules a timer MUST specify a GBA contract responsible for pricing its execution. This GBA must implement a standard interface. Standard Interface: function getGasBid(bytes calldata context) external view returns (TxFeeParams); The protocol supplies the context object, which contains critical data for decision-making:- trigger_block_height (u64): The block height the timer was originally scheduled for.
- current_block_height (u64): The current block height, allowing calculation of delay.
- basefee_cycle (u128): The current basefee for compute cycles.
- basefee_cell (u128): The current basefee for storage/bytes.
- last_block_cycle_usage (u64): The total cycles used in the previous block, as an indicator of congestion.
- owner_actor_balance (u128): The current CBY balance of the actor that owns the timer.
5. DoS Mitigation & Congestion Handling
The combination of a fixed budget and competitive bidding creates a robust defense against DoS attacks.- Bounded Execution: The TIMER_PROCESSING_BUDGET_CYCLES provides a hard cap on the resources consumed by timers in any given block, ensuring that regular user transactions are not crowded out.
- Economic Prioritization: Instead of a simple FIFO queue, the system creates an intra-block auction for the timer budget. Timers deemed more important by their owners (and thus given higher bids by their GBAs) will execute first. Low-priority or “spam” timers will be priced out during periods of congestion.
- Best-Effort Delivery: Timers that are not executed—either due to a low bid or the budget being exhausted—are automatically carried over to the next block’s bucket. This ensures eventual execution and preserves liveness, while still allowing for market-based prioritization.

