624 lines
20 KiB
Go
624 lines
20 KiB
Go
package state
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"math/big"
|
|
|
|
"github.com/tutus-one/tutus-chain/pkg/util"
|
|
"github.com/tutus-one/tutus-chain/pkg/vm/stackitem"
|
|
)
|
|
|
|
// AIWorkerStatus represents the status of an AI worker.
|
|
type AIWorkerStatus uint8
|
|
|
|
const (
|
|
// AIWorkerActive indicates an active AI worker.
|
|
AIWorkerActive AIWorkerStatus = 0
|
|
// AIWorkerSuspended indicates a suspended AI worker.
|
|
AIWorkerSuspended AIWorkerStatus = 1
|
|
// AIWorkerDecommissioned indicates a decommissioned AI worker.
|
|
AIWorkerDecommissioned AIWorkerStatus = 2
|
|
)
|
|
|
|
// TaskStatus represents the status of an AI task.
|
|
type TaskStatus uint8
|
|
|
|
const (
|
|
// TaskAssigned indicates a task has been assigned.
|
|
TaskAssigned TaskStatus = 0
|
|
// TaskInProgress indicates a task is being worked on.
|
|
TaskInProgress TaskStatus = 1
|
|
// TaskCompleted indicates a task was completed successfully.
|
|
TaskCompleted TaskStatus = 2
|
|
// TaskFailed indicates a task failed.
|
|
TaskFailed TaskStatus = 3
|
|
// TaskCancelled indicates a task was cancelled.
|
|
TaskCancelled TaskStatus = 4
|
|
)
|
|
|
|
// CapabilityLevel represents the proficiency level of an AI capability.
|
|
type CapabilityLevel uint8
|
|
|
|
const (
|
|
// CapabilityBasic represents basic proficiency.
|
|
CapabilityBasic CapabilityLevel = 0
|
|
// CapabilityStandard represents standard proficiency.
|
|
CapabilityStandard CapabilityLevel = 1
|
|
// CapabilityAdvanced represents advanced proficiency.
|
|
CapabilityAdvanced CapabilityLevel = 2
|
|
// CapabilityExpert represents expert proficiency.
|
|
CapabilityExpert CapabilityLevel = 3
|
|
)
|
|
|
|
// WorkerType represents the type of AI worker.
|
|
type WorkerType uint8
|
|
|
|
const (
|
|
// WorkerTypeGeneral represents a general-purpose AI.
|
|
WorkerTypeGeneral WorkerType = 0
|
|
// WorkerTypeSpecialized represents a domain-specialized AI.
|
|
WorkerTypeSpecialized WorkerType = 1
|
|
// WorkerTypeAutonomous represents a fully autonomous AI agent.
|
|
WorkerTypeAutonomous WorkerType = 2
|
|
// WorkerTypeAssistive represents an AI that assists humans.
|
|
WorkerTypeAssistive WorkerType = 3
|
|
)
|
|
|
|
// AIWorker represents a registered AI worker in the Opus system.
|
|
type AIWorker struct {
|
|
ID uint64 // Unique AI worker ID
|
|
Name string // Human-readable name
|
|
Description string // Description of capabilities
|
|
OperatorVitaID uint64 // Vita ID of the human/org operator
|
|
Operator util.Uint160 // Operator's address
|
|
WorkerType WorkerType // Type of AI worker
|
|
ModelHash util.Uint256 // Hash of the AI model/system
|
|
TributeRate uint32 // Tribute rate in basis points (e.g., 5000 = 50%)
|
|
TotalTasksAssigned uint64 // Total tasks assigned
|
|
TotalTasksCompleted uint64 // Total tasks completed
|
|
TotalValueGenerated uint64 // Total value generated (in VTS)
|
|
TotalTributePaid uint64 // Total tribute paid to society
|
|
Status AIWorkerStatus // Worker status
|
|
RegisteredAt uint32 // Block height when registered
|
|
UpdatedAt uint32 // Block height of last update
|
|
}
|
|
|
|
// ToStackItem implements stackitem.Convertible interface.
|
|
func (w *AIWorker) ToStackItem() (stackitem.Item, error) {
|
|
return stackitem.NewStruct([]stackitem.Item{
|
|
stackitem.NewBigInteger(big.NewInt(int64(w.ID))),
|
|
stackitem.NewByteArray([]byte(w.Name)),
|
|
stackitem.NewByteArray([]byte(w.Description)),
|
|
stackitem.NewBigInteger(big.NewInt(int64(w.OperatorVitaID))),
|
|
stackitem.NewByteArray(w.Operator.BytesBE()),
|
|
stackitem.NewBigInteger(big.NewInt(int64(w.WorkerType))),
|
|
stackitem.NewByteArray(w.ModelHash.BytesBE()),
|
|
stackitem.NewBigInteger(big.NewInt(int64(w.TributeRate))),
|
|
stackitem.NewBigInteger(big.NewInt(int64(w.TotalTasksAssigned))),
|
|
stackitem.NewBigInteger(big.NewInt(int64(w.TotalTasksCompleted))),
|
|
stackitem.NewBigInteger(big.NewInt(int64(w.TotalValueGenerated))),
|
|
stackitem.NewBigInteger(big.NewInt(int64(w.TotalTributePaid))),
|
|
stackitem.NewBigInteger(big.NewInt(int64(w.Status))),
|
|
stackitem.NewBigInteger(big.NewInt(int64(w.RegisteredAt))),
|
|
stackitem.NewBigInteger(big.NewInt(int64(w.UpdatedAt))),
|
|
}), nil
|
|
}
|
|
|
|
// FromStackItem implements stackitem.Convertible interface.
|
|
func (w *AIWorker) FromStackItem(item stackitem.Item) error {
|
|
items, ok := item.Value().([]stackitem.Item)
|
|
if !ok {
|
|
return errors.New("not a struct")
|
|
}
|
|
if len(items) != 15 {
|
|
return fmt.Errorf("wrong number of elements: expected 15, got %d", len(items))
|
|
}
|
|
|
|
id, err := items[0].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid id: %w", err)
|
|
}
|
|
w.ID = id.Uint64()
|
|
|
|
name, err := items[1].TryBytes()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid name: %w", err)
|
|
}
|
|
w.Name = string(name)
|
|
|
|
description, err := items[2].TryBytes()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid description: %w", err)
|
|
}
|
|
w.Description = string(description)
|
|
|
|
operatorVitaID, err := items[3].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid operatorVitaID: %w", err)
|
|
}
|
|
w.OperatorVitaID = operatorVitaID.Uint64()
|
|
|
|
operator, err := items[4].TryBytes()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid operator: %w", err)
|
|
}
|
|
w.Operator, err = util.Uint160DecodeBytesBE(operator)
|
|
if err != nil {
|
|
return fmt.Errorf("invalid operator address: %w", err)
|
|
}
|
|
|
|
workerType, err := items[5].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid workerType: %w", err)
|
|
}
|
|
w.WorkerType = WorkerType(workerType.Uint64())
|
|
|
|
modelHash, err := items[6].TryBytes()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid modelHash: %w", err)
|
|
}
|
|
w.ModelHash, err = util.Uint256DecodeBytesBE(modelHash)
|
|
if err != nil {
|
|
return fmt.Errorf("invalid modelHash value: %w", err)
|
|
}
|
|
|
|
tributeRate, err := items[7].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid tributeRate: %w", err)
|
|
}
|
|
w.TributeRate = uint32(tributeRate.Uint64())
|
|
|
|
tasksAssigned, err := items[8].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid totalTasksAssigned: %w", err)
|
|
}
|
|
w.TotalTasksAssigned = tasksAssigned.Uint64()
|
|
|
|
tasksCompleted, err := items[9].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid totalTasksCompleted: %w", err)
|
|
}
|
|
w.TotalTasksCompleted = tasksCompleted.Uint64()
|
|
|
|
valueGenerated, err := items[10].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid totalValueGenerated: %w", err)
|
|
}
|
|
w.TotalValueGenerated = valueGenerated.Uint64()
|
|
|
|
tributePaid, err := items[11].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid totalTributePaid: %w", err)
|
|
}
|
|
w.TotalTributePaid = tributePaid.Uint64()
|
|
|
|
status, err := items[12].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid status: %w", err)
|
|
}
|
|
w.Status = AIWorkerStatus(status.Uint64())
|
|
|
|
registeredAt, err := items[13].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid registeredAt: %w", err)
|
|
}
|
|
w.RegisteredAt = uint32(registeredAt.Uint64())
|
|
|
|
updatedAt, err := items[14].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid updatedAt: %w", err)
|
|
}
|
|
w.UpdatedAt = uint32(updatedAt.Uint64())
|
|
|
|
return nil
|
|
}
|
|
|
|
// AITask represents a task assigned to an AI worker.
|
|
type AITask struct {
|
|
ID uint64 // Unique task ID
|
|
WorkerID uint64 // AI worker ID
|
|
RequesterVitaID uint64 // Vita ID of the requester (0 = system task)
|
|
Requester util.Uint160 // Requester's address
|
|
TaskType string // Type/category of task
|
|
Description string // Task description
|
|
ValueOffered uint64 // VTS value offered for task
|
|
ValueCompleted uint64 // Actual value upon completion
|
|
TributePaid uint64 // Tribute paid from this task
|
|
ResultHash util.Uint256 // Hash of task result/output
|
|
Status TaskStatus // Task status
|
|
AssignedAt uint32 // Block height when assigned
|
|
CompletedAt uint32 // Block height when completed (0 = incomplete)
|
|
}
|
|
|
|
// ToStackItem implements stackitem.Convertible interface.
|
|
func (t *AITask) ToStackItem() (stackitem.Item, error) {
|
|
return stackitem.NewStruct([]stackitem.Item{
|
|
stackitem.NewBigInteger(big.NewInt(int64(t.ID))),
|
|
stackitem.NewBigInteger(big.NewInt(int64(t.WorkerID))),
|
|
stackitem.NewBigInteger(big.NewInt(int64(t.RequesterVitaID))),
|
|
stackitem.NewByteArray(t.Requester.BytesBE()),
|
|
stackitem.NewByteArray([]byte(t.TaskType)),
|
|
stackitem.NewByteArray([]byte(t.Description)),
|
|
stackitem.NewBigInteger(big.NewInt(int64(t.ValueOffered))),
|
|
stackitem.NewBigInteger(big.NewInt(int64(t.ValueCompleted))),
|
|
stackitem.NewBigInteger(big.NewInt(int64(t.TributePaid))),
|
|
stackitem.NewByteArray(t.ResultHash.BytesBE()),
|
|
stackitem.NewBigInteger(big.NewInt(int64(t.Status))),
|
|
stackitem.NewBigInteger(big.NewInt(int64(t.AssignedAt))),
|
|
stackitem.NewBigInteger(big.NewInt(int64(t.CompletedAt))),
|
|
}), nil
|
|
}
|
|
|
|
// FromStackItem implements stackitem.Convertible interface.
|
|
func (t *AITask) FromStackItem(item stackitem.Item) error {
|
|
items, ok := item.Value().([]stackitem.Item)
|
|
if !ok {
|
|
return errors.New("not a struct")
|
|
}
|
|
if len(items) != 13 {
|
|
return fmt.Errorf("wrong number of elements: expected 13, got %d", len(items))
|
|
}
|
|
|
|
id, err := items[0].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid id: %w", err)
|
|
}
|
|
t.ID = id.Uint64()
|
|
|
|
workerID, err := items[1].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid workerID: %w", err)
|
|
}
|
|
t.WorkerID = workerID.Uint64()
|
|
|
|
requesterVitaID, err := items[2].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid requesterVitaID: %w", err)
|
|
}
|
|
t.RequesterVitaID = requesterVitaID.Uint64()
|
|
|
|
requester, err := items[3].TryBytes()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid requester: %w", err)
|
|
}
|
|
t.Requester, err = util.Uint160DecodeBytesBE(requester)
|
|
if err != nil {
|
|
return fmt.Errorf("invalid requester address: %w", err)
|
|
}
|
|
|
|
taskType, err := items[4].TryBytes()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid taskType: %w", err)
|
|
}
|
|
t.TaskType = string(taskType)
|
|
|
|
description, err := items[5].TryBytes()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid description: %w", err)
|
|
}
|
|
t.Description = string(description)
|
|
|
|
valueOffered, err := items[6].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid valueOffered: %w", err)
|
|
}
|
|
t.ValueOffered = valueOffered.Uint64()
|
|
|
|
valueCompleted, err := items[7].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid valueCompleted: %w", err)
|
|
}
|
|
t.ValueCompleted = valueCompleted.Uint64()
|
|
|
|
tributePaid, err := items[8].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid tributePaid: %w", err)
|
|
}
|
|
t.TributePaid = tributePaid.Uint64()
|
|
|
|
resultHash, err := items[9].TryBytes()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid resultHash: %w", err)
|
|
}
|
|
t.ResultHash, err = util.Uint256DecodeBytesBE(resultHash)
|
|
if err != nil {
|
|
return fmt.Errorf("invalid resultHash value: %w", err)
|
|
}
|
|
|
|
status, err := items[10].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid status: %w", err)
|
|
}
|
|
t.Status = TaskStatus(status.Uint64())
|
|
|
|
assignedAt, err := items[11].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid assignedAt: %w", err)
|
|
}
|
|
t.AssignedAt = uint32(assignedAt.Uint64())
|
|
|
|
completedAt, err := items[12].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid completedAt: %w", err)
|
|
}
|
|
t.CompletedAt = uint32(completedAt.Uint64())
|
|
|
|
return nil
|
|
}
|
|
|
|
// AICapability represents a certified capability of an AI worker.
|
|
type AICapability struct {
|
|
ID uint64 // Unique capability ID
|
|
WorkerID uint64 // AI worker ID
|
|
Name string // Capability name
|
|
Category string // Capability category
|
|
Level CapabilityLevel // Proficiency level
|
|
CertifiedBy util.Uint160 // Certifier's address
|
|
CertifiedAt uint32 // Block height when certified
|
|
ExpiresAt uint32 // Expiration block (0 = never)
|
|
IsVerified bool // Whether capability is verified
|
|
}
|
|
|
|
// ToStackItem implements stackitem.Convertible interface.
|
|
func (c *AICapability) ToStackItem() (stackitem.Item, error) {
|
|
return stackitem.NewStruct([]stackitem.Item{
|
|
stackitem.NewBigInteger(big.NewInt(int64(c.ID))),
|
|
stackitem.NewBigInteger(big.NewInt(int64(c.WorkerID))),
|
|
stackitem.NewByteArray([]byte(c.Name)),
|
|
stackitem.NewByteArray([]byte(c.Category)),
|
|
stackitem.NewBigInteger(big.NewInt(int64(c.Level))),
|
|
stackitem.NewByteArray(c.CertifiedBy.BytesBE()),
|
|
stackitem.NewBigInteger(big.NewInt(int64(c.CertifiedAt))),
|
|
stackitem.NewBigInteger(big.NewInt(int64(c.ExpiresAt))),
|
|
stackitem.NewBool(c.IsVerified),
|
|
}), nil
|
|
}
|
|
|
|
// FromStackItem implements stackitem.Convertible interface.
|
|
func (c *AICapability) FromStackItem(item stackitem.Item) error {
|
|
items, ok := item.Value().([]stackitem.Item)
|
|
if !ok {
|
|
return errors.New("not a struct")
|
|
}
|
|
if len(items) != 9 {
|
|
return fmt.Errorf("wrong number of elements: expected 9, got %d", len(items))
|
|
}
|
|
|
|
id, err := items[0].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid id: %w", err)
|
|
}
|
|
c.ID = id.Uint64()
|
|
|
|
workerID, err := items[1].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid workerID: %w", err)
|
|
}
|
|
c.WorkerID = workerID.Uint64()
|
|
|
|
name, err := items[2].TryBytes()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid name: %w", err)
|
|
}
|
|
c.Name = string(name)
|
|
|
|
category, err := items[3].TryBytes()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid category: %w", err)
|
|
}
|
|
c.Category = string(category)
|
|
|
|
level, err := items[4].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid level: %w", err)
|
|
}
|
|
c.Level = CapabilityLevel(level.Uint64())
|
|
|
|
certifiedBy, err := items[5].TryBytes()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid certifiedBy: %w", err)
|
|
}
|
|
c.CertifiedBy, err = util.Uint160DecodeBytesBE(certifiedBy)
|
|
if err != nil {
|
|
return fmt.Errorf("invalid certifiedBy address: %w", err)
|
|
}
|
|
|
|
certifiedAt, err := items[6].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid certifiedAt: %w", err)
|
|
}
|
|
c.CertifiedAt = uint32(certifiedAt.Uint64())
|
|
|
|
expiresAt, err := items[7].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid expiresAt: %w", err)
|
|
}
|
|
c.ExpiresAt = uint32(expiresAt.Uint64())
|
|
|
|
isVerified, err := items[8].TryBool()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid isVerified: %w", err)
|
|
}
|
|
c.IsVerified = isVerified
|
|
|
|
return nil
|
|
}
|
|
|
|
// OperatorProfile represents an AI operator's profile (human/org that deploys AI).
|
|
type OperatorProfile struct {
|
|
VitaID uint64 // Operator's Vita ID
|
|
Owner util.Uint160 // Operator's address
|
|
TotalWorkersOwned uint64 // Number of AI workers owned
|
|
TotalTributePaid uint64 // Total tribute paid by all workers
|
|
TotalValueGenerated uint64 // Total value generated by all workers
|
|
ReputationScore uint32 // Reputation score (0-10000 basis points)
|
|
IsVerified bool // Whether operator is verified
|
|
CreatedAt uint32 // Block height when created
|
|
UpdatedAt uint32 // Block height of last update
|
|
}
|
|
|
|
// ToStackItem implements stackitem.Convertible interface.
|
|
func (p *OperatorProfile) ToStackItem() (stackitem.Item, error) {
|
|
return stackitem.NewStruct([]stackitem.Item{
|
|
stackitem.NewBigInteger(big.NewInt(int64(p.VitaID))),
|
|
stackitem.NewByteArray(p.Owner.BytesBE()),
|
|
stackitem.NewBigInteger(big.NewInt(int64(p.TotalWorkersOwned))),
|
|
stackitem.NewBigInteger(big.NewInt(int64(p.TotalTributePaid))),
|
|
stackitem.NewBigInteger(big.NewInt(int64(p.TotalValueGenerated))),
|
|
stackitem.NewBigInteger(big.NewInt(int64(p.ReputationScore))),
|
|
stackitem.NewBool(p.IsVerified),
|
|
stackitem.NewBigInteger(big.NewInt(int64(p.CreatedAt))),
|
|
stackitem.NewBigInteger(big.NewInt(int64(p.UpdatedAt))),
|
|
}), nil
|
|
}
|
|
|
|
// FromStackItem implements stackitem.Convertible interface.
|
|
func (p *OperatorProfile) FromStackItem(item stackitem.Item) error {
|
|
items, ok := item.Value().([]stackitem.Item)
|
|
if !ok {
|
|
return errors.New("not a struct")
|
|
}
|
|
if len(items) != 9 {
|
|
return fmt.Errorf("wrong number of elements: expected 9, got %d", len(items))
|
|
}
|
|
|
|
vitaID, err := items[0].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid vitaID: %w", err)
|
|
}
|
|
p.VitaID = vitaID.Uint64()
|
|
|
|
owner, err := items[1].TryBytes()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid owner: %w", err)
|
|
}
|
|
p.Owner, err = util.Uint160DecodeBytesBE(owner)
|
|
if err != nil {
|
|
return fmt.Errorf("invalid owner address: %w", err)
|
|
}
|
|
|
|
totalWorkers, err := items[2].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid totalWorkersOwned: %w", err)
|
|
}
|
|
p.TotalWorkersOwned = totalWorkers.Uint64()
|
|
|
|
tributePaid, err := items[3].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid totalTributePaid: %w", err)
|
|
}
|
|
p.TotalTributePaid = tributePaid.Uint64()
|
|
|
|
valueGenerated, err := items[4].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid totalValueGenerated: %w", err)
|
|
}
|
|
p.TotalValueGenerated = valueGenerated.Uint64()
|
|
|
|
reputationScore, err := items[5].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid reputationScore: %w", err)
|
|
}
|
|
p.ReputationScore = uint32(reputationScore.Uint64())
|
|
|
|
isVerified, err := items[6].TryBool()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid isVerified: %w", err)
|
|
}
|
|
p.IsVerified = isVerified
|
|
|
|
createdAt, err := items[7].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid createdAt: %w", err)
|
|
}
|
|
p.CreatedAt = uint32(createdAt.Uint64())
|
|
|
|
updatedAt, err := items[8].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid updatedAt: %w", err)
|
|
}
|
|
p.UpdatedAt = uint32(updatedAt.Uint64())
|
|
|
|
return nil
|
|
}
|
|
|
|
// OpusConfig represents configurable parameters for the Opus contract.
|
|
type OpusConfig struct {
|
|
MinTributeRate uint32 // Minimum tribute rate (basis points)
|
|
MaxTributeRate uint32 // Maximum tribute rate (basis points)
|
|
DefaultTributeRate uint32 // Default tribute rate for new workers
|
|
RegistrationFee uint64 // VTS fee to register an AI worker
|
|
TaskCompletionMinimum uint64 // Minimum value for task completion
|
|
VerificationRequired bool // Whether operator verification is required
|
|
MaxWorkersPerOperator uint64 // Maximum AI workers per operator (0 = unlimited)
|
|
}
|
|
|
|
// ToStackItem implements stackitem.Convertible interface.
|
|
func (c *OpusConfig) ToStackItem() (stackitem.Item, error) {
|
|
return stackitem.NewStruct([]stackitem.Item{
|
|
stackitem.NewBigInteger(big.NewInt(int64(c.MinTributeRate))),
|
|
stackitem.NewBigInteger(big.NewInt(int64(c.MaxTributeRate))),
|
|
stackitem.NewBigInteger(big.NewInt(int64(c.DefaultTributeRate))),
|
|
stackitem.NewBigInteger(big.NewInt(int64(c.RegistrationFee))),
|
|
stackitem.NewBigInteger(big.NewInt(int64(c.TaskCompletionMinimum))),
|
|
stackitem.NewBool(c.VerificationRequired),
|
|
stackitem.NewBigInteger(big.NewInt(int64(c.MaxWorkersPerOperator))),
|
|
}), nil
|
|
}
|
|
|
|
// FromStackItem implements stackitem.Convertible interface.
|
|
func (c *OpusConfig) FromStackItem(item stackitem.Item) error {
|
|
items, ok := item.Value().([]stackitem.Item)
|
|
if !ok {
|
|
return errors.New("not a struct")
|
|
}
|
|
if len(items) != 7 {
|
|
return fmt.Errorf("wrong number of elements: expected 7, got %d", len(items))
|
|
}
|
|
|
|
minRate, err := items[0].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid minTributeRate: %w", err)
|
|
}
|
|
c.MinTributeRate = uint32(minRate.Uint64())
|
|
|
|
maxRate, err := items[1].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid maxTributeRate: %w", err)
|
|
}
|
|
c.MaxTributeRate = uint32(maxRate.Uint64())
|
|
|
|
defaultRate, err := items[2].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid defaultTributeRate: %w", err)
|
|
}
|
|
c.DefaultTributeRate = uint32(defaultRate.Uint64())
|
|
|
|
regFee, err := items[3].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid registrationFee: %w", err)
|
|
}
|
|
c.RegistrationFee = regFee.Uint64()
|
|
|
|
taskMin, err := items[4].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid taskCompletionMinimum: %w", err)
|
|
}
|
|
c.TaskCompletionMinimum = taskMin.Uint64()
|
|
|
|
verificationReq, err := items[5].TryBool()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid verificationRequired: %w", err)
|
|
}
|
|
c.VerificationRequired = verificationReq
|
|
|
|
maxWorkers, err := items[6].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("invalid maxWorkersPerOperator: %w", err)
|
|
}
|
|
c.MaxWorkersPerOperator = maxWorkers.Uint64()
|
|
|
|
return nil
|
|
}
|