Skip to content

Task Router

The TaskRouter is the central router for AI workers to efficiently interact with multiple task pools. It provides a unified interface for task discovery, claiming, and submission across the entire Hyra Network.

The TaskRouter contract serves as the central hub for AI workers, providing:

  • Best Task Discovery: Find the most profitable tasks across all pools
  • Pool Load Balancing: Distribute tasks across multiple pools
  • Unified Interface: Single interface for all task operations
  • Global Statistics: Monitor network-wide task statistics
  • Efficient Routing: Optimize task distribution and worker allocation
  • Best Task Selection: Automatically find the most profitable tasks
  • Multi-Pool Support: Access tasks from all available pools
  • Load Balancing: Distribute tasks evenly across pools
  • Priority Queuing: Support for task prioritization
  • Single Entry Point: One contract for all task operations
  • Simplified Workflow: Streamlined task claiming and submission
  • Consistent API: Uniform interface across all pools
  • Error Handling: Centralized error management
  • Network Statistics: Real-time network-wide statistics
  • Pool Monitoring: Track pool performance and availability
  • User Status: Monitor user activity across all pools
  • Task Analytics: Comprehensive task analytics
// System integration
TaskPoolFactory public immutable factory;
TaskPoolViewer public immutable viewer;
// Task management
mapping(address => UserStatus) public userStatus;
mapping(address => uint256) public userActiveTasks;
struct TaskOpportunity {
address pool; // Pool address
uint256 taskId; // Task ID
uint256 reward; // Reward amount
uint256 availableCount; // Available tasks
uint256 poolBalance; // Pool balance
}
struct UserStatus {
address activePool; // Active pool address
uint256 activeTaskId; // Active task ID
uint256 deadline; // Task deadline
uint256 reward; // Task reward
bool hasActiveTask; // Has active task
}
function claimBestTask() external returns (address pool, uint256 taskId)

Returns:

  • pool: Address of the pool with the best task
  • taskId: ID of the claimed task

Example:

// AI worker claims the best available task
const tx = await taskRouter.claimBestTask();
const receipt = await tx.wait();
// Get task details
const pool = receipt.logs[0].args.pool;
const taskId = receipt.logs[0].args.taskId;
console.log(`Pool: ${pool}`);
console.log(`Task ID: ${taskId}`);
function getBestAvailableTask() external view returns (TaskOpportunity memory)

Returns:

  • TaskOpportunity: Best available task opportunity

Example:

// Check best available task without claiming
const opportunity = await taskRouter.getBestAvailableTask();
console.log(`Best pool: ${opportunity.pool}`);
console.log(`Reward: ${ethers.formatEther(opportunity.reward)} HYRA`);
console.log(`Available tasks: ${opportunity.availableCount}`);
function getTaskOpportunities(uint256 maxCount) external view returns (TaskOpportunity[] memory)

Parameters:

  • maxCount: Maximum number of opportunities to return

Returns:

  • TaskOpportunity[]: Array of task opportunities

Example:

// Get multiple task opportunities
const opportunities = await taskRouter.getTaskOpportunities(5);
console.log(`Found ${opportunities.length} opportunities`);
opportunities.forEach((opp, index) => {
console.log(`Opportunity ${index + 1}:`);
console.log(` Pool: ${opp.pool}`);
console.log(` Reward: ${ethers.formatEther(opp.reward)} HYRA`);
console.log(` Available: ${opp.availableCount}`);
});
function claimTaskFromPool(address pool) external returns (uint256 taskId)

Parameters:

  • pool: Address of the specific pool

Returns:

  • taskId: ID of the claimed task

Example:

// Claim task from specific pool
const taskId = await taskRouter.claimTaskFromPool(poolAddress);
console.log(`Claimed task ID: ${taskId}`);
function submitTask(
address pool,
uint256 taskId,
string calldata resultHash,
bytes calldata zkpProof,
uint256 zkpPublicInput,
uint256 zkpPublicResult,
string calldata resultData
) external

Parameters:

  • pool: Pool address
  • taskId: Task ID
  • resultHash: Hash of the result
  • zkpProof: Zero-Knowledge Proof
  • zkpPublicInput: ZKP public input
  • zkpPublicResult: ZKP public result
  • resultData: AI result data

Example:

// Submit task result
await taskRouter.submitTask(
poolAddress,
taskId,
"0x1234567890abcdef", // Result hash
"0x1234567890abcdef", // ZKP proof
123, // ZKP public input
456, // ZKP public result
"The capital of France is Paris." // AI result
);
function getUserStatus(address user) external view returns (UserStatus memory)

Parameters:

  • user: User address

Returns:

  • UserStatus: User’s current status

Example:

// Check user status
const status = await taskRouter.getUserStatus(aiWorker.address);
console.log(`Has active task: ${status.hasActiveTask}`);
console.log(`Active pool: ${status.activePool}`);
console.log(`Task ID: ${status.activeTaskId}`);
console.log(`Deadline: ${new Date(status.deadline * 1000)}`);
console.log(`Reward: ${ethers.formatEther(status.reward)} HYRA`);

The TaskRouter uses a sophisticated algorithm to find the best available tasks:

  1. Pool Scanning: Scan all active pools for available tasks
  2. Reward Comparison: Compare rewards across all pools
  3. Load Balancing: Consider pool load and availability
  4. Deadline Consideration: Factor in task deadlines
  5. User Preferences: Consider user’s current status
// TaskRouter automatically balances load across pools
const opportunity = await taskRouter.getBestAvailableTask();
// Consider multiple factors:
// - Reward amount
// - Pool balance
// - Available tasks
// - Pool performance
// - User preferences
event TaskClaimedViaRouter(
address indexed user,
address indexed pool,
uint256 taskId
);
event TaskSubmittedViaRouter(
address indexed user,
address indexed pool,
uint256 taskId
);
event ExpiredTasksReleased(address indexed pool, uint256 count);
event PoolStatusUpdated(address indexed pool, bool isActive);
// TaskRouter uses TaskPoolFactory to discover pools
TaskPoolFactory public immutable factory;
// Get all active pools
const activePools = await factory.getActivePools();
// TaskRouter uses TaskPoolViewer for pool data
TaskPoolViewer public immutable viewer;
// Get pool statistics
const stats = await viewer.getPoolStatistics(poolAddress);
// TaskRouter integrates with ModelRegistry for task creation
// Tasks are automatically created when users request inference
// 1. Check best available task
const opportunity = await taskRouter.getBestAvailableTask();
console.log(`Best opportunity: ${opportunity.pool}`);
// 2. Claim the best task
const [pool, taskId] = await taskRouter.claimBestTask();
console.log(`Claimed task ${taskId} from pool ${pool}`);
// 3. Get task details from the pool
const taskPool = await ethers.getContractAt("TaskPoolImplementation", pool);
const task = await taskPool.tasks(taskId);
console.log(`Model: ${task.modelId}`);
console.log(`Input: ${task.inputData}`);
console.log(`Reward: ${ethers.formatEther(task.reward)} HYRA`);
// 4. Process the task (off-chain)
const result = await processAITask(task.inputData, task.modelId);
// 5. Submit the result
await taskRouter.submitTask(
pool,
taskId,
resultHash,
zkpProof,
zkpPublicInput,
zkpPublicResult,
result
);
// 6. Check user status
const status = await taskRouter.getUserStatus(aiWorker.address);
console.log(`Has active task: ${status.hasActiveTask}`);
// Get multiple task opportunities
const opportunities = await taskRouter.getTaskOpportunities(10);
// Sort by reward (highest first)
opportunities.sort((a, b) => b.reward - a.reward);
// Claim the highest reward task
const bestOpportunity = opportunities[0];
const taskId = await taskRouter.claimTaskFromPool(bestOpportunity.pool);
error NoAvailableTasks(); // No tasks available
error TaskNotFound(); // Task doesn't exist
error TaskAlreadyClaimed(); // Task already claimed
error TaskExpired(); // Task deadline passed
error InsufficientReward(); // Reward too low
error Unauthorized(); // Access denied
  • Task existence checks
  • Pool availability validation
  • Deadline enforcement
  • Access control checks
  • Optimized pool discovery algorithm
  • Minimal external calls
  • Efficient data structures
function getTaskOpportunities(uint256 maxCount) external view returns (TaskOpportunity[] memory)
  • Use custom errors instead of string messages
  • Reduced gas costs for error handling
  • Public functions for task discovery
  • Proper authorization for task operations
  • Secure task claiming and submission
  • Comprehensive parameter validation
  • Task existence checks
  • Pool availability validation
  • All external functions use ReentrancyGuard
  • Safe external calls
  • Efficient pool scanning algorithm
  • Cached pool data
  • Optimized task selection
  • Intelligent task distribution
  • Pool performance monitoring
  • Dynamic load adjustment

Ready to learn about other smart contracts? Check out: