move repos into monorepo

This commit is contained in:
Timur Gordon
2025-11-13 20:44:00 +01:00
commit 4b23e5eb7f
204 changed files with 33737 additions and 0 deletions

View File

@@ -0,0 +1,126 @@
use crate::store::BaseData;
use rhai::{CustomType, TypeBuilder};
use serde::{Deserialize, Serialize};
/// Bid status enumeration
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
pub enum BidStatus {
#[default]
Pending,
Confirmed,
Assigned,
Cancelled,
Done,
}
/// Billing period enumeration
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
pub enum BillingPeriod {
#[default]
Hourly,
Monthly,
Yearly,
Biannually,
Triannually,
}
/// I can bid for infra, and optionally get accepted
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default, crate::DeriveObject)]
pub struct Bid {
pub base_data: BaseData,
/// links back to customer for this capacity (user on ledger)
#[index]
pub customer_id: u32,
/// nr of slices I need in 1 machine
pub compute_slices_nr: i32,
/// price per 1 GB slice I want to accept
pub compute_slice_price: f64,
/// nr of storage slices needed
pub storage_slices_nr: i32,
/// price per 1 GB storage slice I want to accept
pub storage_slice_price: f64,
pub status: BidStatus,
/// if obligation then will be charged and money needs to be in escrow, otherwise its an intent
pub obligation: bool,
/// epoch timestamp
pub start_date: u32,
/// epoch timestamp
pub end_date: u32,
/// signature as done by a user/consumer to validate their identity and intent
pub signature_user: String,
pub billing_period: BillingPeriod,
}
impl Bid {
pub fn new() -> Self {
Self {
base_data: BaseData::new(),
customer_id: 0,
compute_slices_nr: 0,
compute_slice_price: 0.0,
storage_slices_nr: 0,
storage_slice_price: 0.0,
status: BidStatus::default(),
obligation: false,
start_date: 0,
end_date: 0,
signature_user: String::new(),
billing_period: BillingPeriod::default(),
}
}
pub fn customer_id(mut self, v: u32) -> Self {
self.customer_id = v;
self
}
pub fn compute_slices_nr(mut self, v: i32) -> Self {
self.compute_slices_nr = v;
self
}
pub fn compute_slice_price(mut self, v: f64) -> Self {
self.compute_slice_price = v;
self
}
pub fn storage_slices_nr(mut self, v: i32) -> Self {
self.storage_slices_nr = v;
self
}
pub fn storage_slice_price(mut self, v: f64) -> Self {
self.storage_slice_price = v;
self
}
pub fn status(mut self, v: BidStatus) -> Self {
self.status = v;
self
}
pub fn obligation(mut self, v: bool) -> Self {
self.obligation = v;
self
}
pub fn start_date(mut self, v: u32) -> Self {
self.start_date = v;
self
}
pub fn end_date(mut self, v: u32) -> Self {
self.end_date = v;
self
}
pub fn signature_user(mut self, v: impl ToString) -> Self {
self.signature_user = v.to_string();
self
}
pub fn billing_period(mut self, v: BillingPeriod) -> Self {
self.billing_period = v;
self
}
}

View File

@@ -0,0 +1,39 @@
use rhai::{CustomType, TypeBuilder};
use serde::{Deserialize, Serialize};
/// SLA policy matching the V spec `SLAPolicy`
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
pub struct SLAPolicy {
/// should +90
pub sla_uptime: i32,
/// minimal mbits we can expect avg over 1h per node, 0 means we don't guarantee
pub sla_bandwidth_mbit: i32,
/// 0-100, percent of money given back in relation to month if sla breached,
/// e.g. 200 means we return 2 months worth of rev if sla missed
pub sla_penalty: i32,
}
impl SLAPolicy {
pub fn new() -> Self { Self::default() }
pub fn sla_uptime(mut self, v: i32) -> Self { self.sla_uptime = v; self }
pub fn sla_bandwidth_mbit(mut self, v: i32) -> Self { self.sla_bandwidth_mbit = v; self }
pub fn sla_penalty(mut self, v: i32) -> Self { self.sla_penalty = v; self }
pub fn build(self) -> Self { self }
}
/// Pricing policy matching the V spec `PricingPolicy`
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
pub struct PricingPolicy {
/// e.g. 30,40,50 means if user has more CC in wallet than 1 year utilization
/// then this provider gives 30%, 2Y 40%, ...
pub marketplace_year_discounts: Vec<i32>,
/// e.g. 10,20,30
pub volume_discounts: Vec<i32>,
}
impl PricingPolicy {
pub fn new() -> Self { Self { marketplace_year_discounts: vec![30, 40, 50], volume_discounts: vec![10, 20, 30] } }
pub fn marketplace_year_discounts(mut self, v: Vec<i32>) -> Self { self.marketplace_year_discounts = v; self }
pub fn volume_discounts(mut self, v: Vec<i32>) -> Self { self.volume_discounts = v; self }
pub fn build(self) -> Self { self }
}

View File

@@ -0,0 +1,217 @@
use crate::store::BaseData;
use rhai::{CustomType, TypeBuilder};
use serde::{Deserialize, Serialize};
use super::bid::BillingPeriod;
/// Contract status enumeration
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
pub enum ContractStatus {
#[default]
Active,
Cancelled,
Error,
Paused,
}
/// Compute slice provisioned for a contract
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
pub struct ComputeSliceProvisioned {
pub node_id: u32,
/// the id of the slice in the node
pub id: u16,
pub mem_gb: f64,
pub storage_gb: f64,
pub passmark: i32,
pub vcores: i32,
pub cpu_oversubscription: i32,
pub tags: String,
}
/// Storage slice provisioned for a contract
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
pub struct StorageSliceProvisioned {
pub node_id: u32,
/// the id of the slice in the node, are tracked in the node itself
pub id: u16,
pub storage_size_gb: i32,
pub tags: String,
}
/// Contract for provisioned infrastructure
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default, crate::DeriveObject)]
pub struct Contract {
pub base_data: BaseData,
/// links back to customer for this capacity (user on ledger)
#[index]
pub customer_id: u32,
pub compute_slices: Vec<ComputeSliceProvisioned>,
pub storage_slices: Vec<StorageSliceProvisioned>,
/// price per 1 GB agreed upon
pub compute_slice_price: f64,
/// price per 1 GB agreed upon
pub storage_slice_price: f64,
/// price per 1 GB agreed upon (transfer)
pub network_slice_price: f64,
pub status: ContractStatus,
/// epoch timestamp
pub start_date: u32,
/// epoch timestamp
pub end_date: u32,
/// signature as done by a user/consumer to validate their identity and intent
pub signature_user: String,
/// signature as done by the hoster
pub signature_hoster: String,
pub billing_period: BillingPeriod,
}
impl Contract {
pub fn new() -> Self {
Self {
base_data: BaseData::new(),
customer_id: 0,
compute_slices: Vec::new(),
storage_slices: Vec::new(),
compute_slice_price: 0.0,
storage_slice_price: 0.0,
network_slice_price: 0.0,
status: ContractStatus::default(),
start_date: 0,
end_date: 0,
signature_user: String::new(),
signature_hoster: String::new(),
billing_period: BillingPeriod::default(),
}
}
pub fn customer_id(mut self, v: u32) -> Self {
self.customer_id = v;
self
}
pub fn add_compute_slice(mut self, slice: ComputeSliceProvisioned) -> Self {
self.compute_slices.push(slice);
self
}
pub fn add_storage_slice(mut self, slice: StorageSliceProvisioned) -> Self {
self.storage_slices.push(slice);
self
}
pub fn compute_slice_price(mut self, v: f64) -> Self {
self.compute_slice_price = v;
self
}
pub fn storage_slice_price(mut self, v: f64) -> Self {
self.storage_slice_price = v;
self
}
pub fn network_slice_price(mut self, v: f64) -> Self {
self.network_slice_price = v;
self
}
pub fn status(mut self, v: ContractStatus) -> Self {
self.status = v;
self
}
pub fn start_date(mut self, v: u32) -> Self {
self.start_date = v;
self
}
pub fn end_date(mut self, v: u32) -> Self {
self.end_date = v;
self
}
pub fn signature_user(mut self, v: impl ToString) -> Self {
self.signature_user = v.to_string();
self
}
pub fn signature_hoster(mut self, v: impl ToString) -> Self {
self.signature_hoster = v.to_string();
self
}
pub fn billing_period(mut self, v: BillingPeriod) -> Self {
self.billing_period = v;
self
}
}
impl ComputeSliceProvisioned {
pub fn new() -> Self {
Self::default()
}
pub fn node_id(mut self, v: u32) -> Self {
self.node_id = v;
self
}
pub fn id(mut self, v: u16) -> Self {
self.id = v;
self
}
pub fn mem_gb(mut self, v: f64) -> Self {
self.mem_gb = v;
self
}
pub fn storage_gb(mut self, v: f64) -> Self {
self.storage_gb = v;
self
}
pub fn passmark(mut self, v: i32) -> Self {
self.passmark = v;
self
}
pub fn vcores(mut self, v: i32) -> Self {
self.vcores = v;
self
}
pub fn cpu_oversubscription(mut self, v: i32) -> Self {
self.cpu_oversubscription = v;
self
}
pub fn tags(mut self, v: impl ToString) -> Self {
self.tags = v.to_string();
self
}
}
impl StorageSliceProvisioned {
pub fn new() -> Self {
Self::default()
}
pub fn node_id(mut self, v: u32) -> Self {
self.node_id = v;
self
}
pub fn id(mut self, v: u16) -> Self {
self.id = v;
self
}
pub fn storage_size_gb(mut self, v: i32) -> Self {
self.storage_size_gb = v;
self
}
pub fn tags(mut self, v: impl ToString) -> Self {
self.tags = v.to_string();
self
}
}

View File

@@ -0,0 +1,18 @@
pub mod bid;
pub mod common;
pub mod contract;
pub mod node;
pub mod nodegroup;
pub mod reputation;
pub mod reservation;
pub use bid::{Bid, BidStatus, BillingPeriod};
pub use common::{PricingPolicy, SLAPolicy};
pub use contract::{Contract, ContractStatus, ComputeSliceProvisioned, StorageSliceProvisioned};
pub use node::{
CPUDevice, ComputeSlice, DeviceInfo, GPUDevice, MemoryDevice, NetworkDevice, Node,
NodeCapacity, StorageDevice, StorageSlice,
};
pub use nodegroup::NodeGroup;
pub use reputation::{NodeGroupReputation, NodeReputation};
pub use reservation::{Reservation, ReservationStatus};

View File

@@ -0,0 +1,279 @@
use crate::store::BaseData;
use rhai::{CustomType, TypeBuilder};
use serde::{Deserialize, Serialize};
use super::common::{PricingPolicy, SLAPolicy};
/// Storage device information
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
pub struct StorageDevice {
/// can be used in node
pub id: String,
/// Size of the storage device in gigabytes
pub size_gb: f64,
/// Description of the storage device
pub description: String,
}
/// Memory device information
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
pub struct MemoryDevice {
/// can be used in node
pub id: String,
/// Size of the memory device in gigabytes
pub size_gb: f64,
/// Description of the memory device
pub description: String,
}
/// CPU device information
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
pub struct CPUDevice {
/// can be used in node
pub id: String,
/// Number of CPU cores
pub cores: i32,
/// Passmark score
pub passmark: i32,
/// Description of the CPU
pub description: String,
/// Brand of the CPU
pub cpu_brand: String,
/// Version of the CPU
pub cpu_version: String,
}
/// GPU device information
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
pub struct GPUDevice {
/// can be used in node
pub id: String,
/// Number of GPU cores
pub cores: i32,
/// Size of the GPU memory in gigabytes
pub memory_gb: f64,
/// Description of the GPU
pub description: String,
pub gpu_brand: String,
pub gpu_version: String,
}
/// Network device information
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
pub struct NetworkDevice {
/// can be used in node
pub id: String,
/// Network speed in Mbps
pub speed_mbps: i32,
/// Description of the network device
pub description: String,
}
/// Aggregated device info for a node
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
pub struct DeviceInfo {
pub vendor: String,
pub storage: Vec<StorageDevice>,
pub memory: Vec<MemoryDevice>,
pub cpu: Vec<CPUDevice>,
pub gpu: Vec<GPUDevice>,
pub network: Vec<NetworkDevice>,
}
/// NodeCapacity represents the hardware capacity details of a node.
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
pub struct NodeCapacity {
/// Total storage in gigabytes
pub storage_gb: f64,
/// Total memory in gigabytes
pub mem_gb: f64,
/// Total GPU memory in gigabytes
pub mem_gb_gpu: f64,
/// Passmark score for the node
pub passmark: i32,
/// Total virtual cores
pub vcores: i32,
}
// PricingPolicy and SLAPolicy moved to `common.rs` to be shared across models.
/// Compute slice (typically represents a base unit of compute)
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
pub struct ComputeSlice {
/// the id of the slice in the node
pub id: u16,
pub mem_gb: f64,
pub storage_gb: f64,
pub passmark: i32,
pub vcores: i32,
pub cpu_oversubscription: i32,
pub storage_oversubscription: i32,
/// nr of GPU's see node to know what GPU's are
pub gpus: u8,
}
impl ComputeSlice {
pub fn new() -> Self {
Self {
id: 0,
mem_gb: 0.0,
storage_gb: 0.0,
passmark: 0,
vcores: 0,
cpu_oversubscription: 0,
storage_oversubscription: 0,
gpus: 0,
}
}
pub fn id(mut self, id: u16) -> Self {
self.id = id;
self
}
pub fn mem_gb(mut self, v: f64) -> Self {
self.mem_gb = v;
self
}
pub fn storage_gb(mut self, v: f64) -> Self {
self.storage_gb = v;
self
}
pub fn passmark(mut self, v: i32) -> Self {
self.passmark = v;
self
}
pub fn vcores(mut self, v: i32) -> Self {
self.vcores = v;
self
}
pub fn cpu_oversubscription(mut self, v: i32) -> Self {
self.cpu_oversubscription = v;
self
}
pub fn storage_oversubscription(mut self, v: i32) -> Self {
self.storage_oversubscription = v;
self
}
pub fn gpus(mut self, v: u8) -> Self {
self.gpus = v;
self
}
}
/// Storage slice (typically 1GB of storage)
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
pub struct StorageSlice {
/// the id of the slice in the node, are tracked in the node itself
pub id: u16,
}
impl StorageSlice {
pub fn new() -> Self {
Self {
id: 0,
}
}
pub fn id(mut self, id: u16) -> Self {
self.id = id;
self
}
}
/// Grid4 Node model
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default, crate::DeriveObject)]
pub struct Node {
pub base_data: BaseData,
/// Link to node group
#[index]
pub nodegroupid: i32,
/// Uptime percentage 0..100
pub uptime: i32,
pub computeslices: Vec<ComputeSlice>,
pub storageslices: Vec<StorageSlice>,
pub devices: DeviceInfo,
/// 2 letter code as specified in lib/data/countries/data/countryInfo.txt
#[index]
pub country: String,
/// Hardware capacity details
pub capacity: NodeCapacity,
/// first time node was active
pub birthtime: u32,
/// node public key
#[index]
pub pubkey: String,
/// signature done on node to validate pubkey with privkey
pub signature_node: String,
/// signature as done by farmers to validate their identity
pub signature_farmer: String,
}
impl Node {
pub fn new() -> Self {
Self {
base_data: BaseData::new(),
nodegroupid: 0,
uptime: 0,
computeslices: Vec::new(),
storageslices: Vec::new(),
devices: DeviceInfo::default(),
country: String::new(),
capacity: NodeCapacity::default(),
birthtime: 0,
pubkey: String::new(),
signature_node: String::new(),
signature_farmer: String::new(),
}
}
pub fn nodegroupid(mut self, v: i32) -> Self {
self.nodegroupid = v;
self
}
pub fn uptime(mut self, v: i32) -> Self {
self.uptime = v;
self
}
pub fn add_compute_slice(mut self, s: ComputeSlice) -> Self {
self.computeslices.push(s);
self
}
pub fn add_storage_slice(mut self, s: StorageSlice) -> Self {
self.storageslices.push(s);
self
}
pub fn devices(mut self, d: DeviceInfo) -> Self {
self.devices = d;
self
}
pub fn country(mut self, c: impl ToString) -> Self {
self.country = c.to_string();
self
}
pub fn capacity(mut self, c: NodeCapacity) -> Self {
self.capacity = c;
self
}
pub fn birthtime(mut self, t: u32) -> Self {
self.birthtime = t;
self
}
pub fn pubkey(mut self, v: impl ToString) -> Self {
self.pubkey = v.to_string();
self
}
pub fn signature_node(mut self, v: impl ToString) -> Self {
self.signature_node = v.to_string();
self
}
pub fn signature_farmer(mut self, v: impl ToString) -> Self {
self.signature_farmer = v.to_string();
self
}
/// Placeholder for capacity recalculation out of the devices on the Node
pub fn check(self) -> Self {
// TODO: calculate NodeCapacity out of the devices on the Node
self
}
}

View File

@@ -0,0 +1,50 @@
use crate::store::BaseData;
use rhai::{CustomType, TypeBuilder};
use serde::{Deserialize, Serialize};
use super::common::{PricingPolicy, SLAPolicy};
/// Grid4 NodeGroup model (root object for farmer configuration)
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default, crate::DeriveObject)]
pub struct NodeGroup {
pub base_data: BaseData,
/// link back to farmer who owns the nodegroup, is a user?
#[index]
pub farmerid: u32,
/// only visible by farmer, in future encrypted, used to boot a node
pub secret: String,
pub description: String,
pub slapolicy: SLAPolicy,
pub pricingpolicy: PricingPolicy,
/// pricing in CC - cloud credit, per 2GB node slice
pub compute_slice_normalized_pricing_cc: f64,
/// pricing in CC - cloud credit, per 1GB storage slice
pub storage_slice_normalized_pricing_cc: f64,
/// signature as done by farmers to validate that they created this group
pub signature_farmer: String,
}
impl NodeGroup {
pub fn new() -> Self {
Self {
base_data: BaseData::new(),
farmerid: 0,
secret: String::new(),
description: String::new(),
slapolicy: SLAPolicy::default(),
pricingpolicy: PricingPolicy::new(),
compute_slice_normalized_pricing_cc: 0.0,
storage_slice_normalized_pricing_cc: 0.0,
signature_farmer: String::new(),
}
}
pub fn farmerid(mut self, v: u32) -> Self { self.farmerid = v; self }
pub fn secret(mut self, v: impl ToString) -> Self { self.secret = v.to_string(); self }
pub fn description(mut self, v: impl ToString) -> Self { self.description = v.to_string(); self }
pub fn slapolicy(mut self, v: SLAPolicy) -> Self { self.slapolicy = v; self }
pub fn pricingpolicy(mut self, v: PricingPolicy) -> Self { self.pricingpolicy = v; self }
pub fn compute_slice_normalized_pricing_cc(mut self, v: f64) -> Self { self.compute_slice_normalized_pricing_cc = v; self }
pub fn storage_slice_normalized_pricing_cc(mut self, v: f64) -> Self { self.storage_slice_normalized_pricing_cc = v; self }
pub fn signature_farmer(mut self, v: impl ToString) -> Self { self.signature_farmer = v.to_string(); self }
}

View File

@@ -0,0 +1,83 @@
use crate::store::BaseData;
use rhai::{CustomType, TypeBuilder};
use serde::{Deserialize, Serialize};
/// Node reputation information
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
pub struct NodeReputation {
pub node_id: u32,
/// between 0 and 100, earned over time
pub reputation: i32,
/// between 0 and 100, set by system, farmer has no ability to set this
pub uptime: i32,
}
/// NodeGroup reputation model
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default, crate::DeriveObject)]
pub struct NodeGroupReputation {
pub base_data: BaseData,
#[index]
pub nodegroup_id: u32,
/// between 0 and 100, earned over time
pub reputation: i32,
/// between 0 and 100, set by system, farmer has no ability to set this
pub uptime: i32,
pub nodes: Vec<NodeReputation>,
}
impl NodeGroupReputation {
pub fn new() -> Self {
Self {
base_data: BaseData::new(),
nodegroup_id: 0,
reputation: 50, // default as per spec
uptime: 0,
nodes: Vec::new(),
}
}
pub fn nodegroup_id(mut self, v: u32) -> Self {
self.nodegroup_id = v;
self
}
pub fn reputation(mut self, v: i32) -> Self {
self.reputation = v;
self
}
pub fn uptime(mut self, v: i32) -> Self {
self.uptime = v;
self
}
pub fn add_node_reputation(mut self, node_rep: NodeReputation) -> Self {
self.nodes.push(node_rep);
self
}
}
impl NodeReputation {
pub fn new() -> Self {
Self {
node_id: 0,
reputation: 50, // default as per spec
uptime: 0,
}
}
pub fn node_id(mut self, v: u32) -> Self {
self.node_id = v;
self
}
pub fn reputation(mut self, v: i32) -> Self {
self.reputation = v;
self
}
pub fn uptime(mut self, v: i32) -> Self {
self.uptime = v;
self
}
}

View File

@@ -0,0 +1,56 @@
use crate::store::BaseData;
use rhai::{CustomType, TypeBuilder};
use serde::{Deserialize, Serialize};
/// Reservation status as per V spec
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
pub enum ReservationStatus {
#[default]
Pending,
Confirmed,
Assigned,
Cancelled,
Done,
}
/// Grid4 Reservation model
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default, crate::DeriveObject)]
pub struct Reservation {
pub base_data: BaseData,
/// links back to customer for this capacity
#[index]
pub customer_id: u32,
pub compute_slices: Vec<u32>,
pub storage_slices: Vec<u32>,
pub status: ReservationStatus,
/// if obligation then will be charged and money needs to be in escrow, otherwise its an intent
pub obligation: bool,
/// epoch
pub start_date: u32,
pub end_date: u32,
}
impl Reservation {
pub fn new() -> Self {
Self {
base_data: BaseData::new(),
customer_id: 0,
compute_slices: Vec::new(),
storage_slices: Vec::new(),
status: ReservationStatus::Pending,
obligation: false,
start_date: 0,
end_date: 0,
}
}
pub fn customer_id(mut self, v: u32) -> Self { self.customer_id = v; self }
pub fn add_compute_slice(mut self, id: u32) -> Self { self.compute_slices.push(id); self }
pub fn compute_slices(mut self, v: Vec<u32>) -> Self { self.compute_slices = v; self }
pub fn add_storage_slice(mut self, id: u32) -> Self { self.storage_slices.push(id); self }
pub fn storage_slices(mut self, v: Vec<u32>) -> Self { self.storage_slices = v; self }
pub fn status(mut self, v: ReservationStatus) -> Self { self.status = v; self }
pub fn obligation(mut self, v: bool) -> Self { self.obligation = v; self }
pub fn start_date(mut self, v: u32) -> Self { self.start_date = v; self }
pub fn end_date(mut self, v: u32) -> Self { self.end_date = v; self }
}

View File

@@ -0,0 +1,194 @@
# Grid4 Data Model
This module defines data models for nodes, groups, and slices in a cloud/grid infrastructure. Each root object is marked with `@[heap]` and can be indexed for efficient querying.
## Root Objects Overview
| Object | Description | Index Fields |
| ----------- | --------------------------------------------- | ------------------------------ |
| `Node` | Represents a single node in the grid | `id`, `nodegroupid`, `country` |
| `NodeGroup` | Represents a group of nodes owned by a farmer | `id`, `farmerid` |
---
## Node
Represents a single node in the grid with slices, devices, and capacity.
| Field | Type | Description | Indexed |
| --------------- | ---------------- | -------------------------------------------- | ------- |
| `id` | `int` | Unique node ID | ✅ |
| `nodegroupid` | `int` | ID of the owning node group | ✅ |
| `uptime` | `int` | Uptime percentage (0-100) | ✅ |
| `computeslices` | `[]ComputeSlice` | List of compute slices | ❌ |
| `storageslices` | `[]StorageSlice` | List of storage slices | ❌ |
| `devices` | `DeviceInfo` | Hardware device info (storage, memory, etc.) | ❌ |
| `country` | `string` | 2-letter country code | ✅ |
| `capacity` | `NodeCapacity` | Aggregated hardware capacity | ❌ |
| `provisiontime` | `u32` | Provisioning time (simple/compatible format) | ✅ |
---
## NodeGroup
Represents a group of nodes owned by a farmer, with policies.
| Field | Type | Description | Indexed |
| ------------------------------------- | --------------- | ---------------------------------------------- | ------- |
| `id` | `u32` | Unique group ID | ✅ |
| `farmerid` | `u32` | Farmer/user ID | ✅ |
| `secret` | `string` | Encrypted secret for booting nodes | ❌ |
| `description` | `string` | Group description | ❌ |
| `slapolicy` | `SLAPolicy` | SLA policy details | ❌ |
| `pricingpolicy` | `PricingPolicy` | Pricing policy details | ❌ |
| `compute_slice_normalized_pricing_cc` | `f64` | Pricing per 2GB compute slice in cloud credits | ❌ |
| `storage_slice_normalized_pricing_cc` | `f64` | Pricing per 1GB storage slice in cloud credits | ❌ |
| `reputation` | `int` | Reputation (0-100) | ✅ |
| `uptime` | `int` | Uptime (0-100) | ✅ |
---
## ComputeSlice
Represents a compute slice (e.g., 1GB memory unit).
| Field | Type | Description |
| -------------------------- | --------------- | -------------------------------- |
| `nodeid` | `u32` | Owning node ID |
| `id` | `int` | Slice ID in node |
| `mem_gb` | `f64` | Memory in GB |
| `storage_gb` | `f64` | Storage in GB |
| `passmark` | `int` | Passmark score |
| `vcores` | `int` | Virtual cores |
| `cpu_oversubscription` | `int` | CPU oversubscription ratio |
| `storage_oversubscription` | `int` | Storage oversubscription ratio |
| `price_range` | `[]f64` | Price range [min, max] |
| `gpus` | `u8` | Number of GPUs |
| `price_cc` | `f64` | Price per slice in cloud credits |
| `pricing_policy` | `PricingPolicy` | Pricing policy |
| `sla_policy` | `SLAPolicy` | SLA policy |
---
## StorageSlice
Represents a 1GB storage slice.
| Field | Type | Description |
| ---------------- | --------------- | -------------------------------- |
| `nodeid` | `u32` | Owning node ID |
| `id` | `int` | Slice ID in node |
| `price_cc` | `f64` | Price per slice in cloud credits |
| `pricing_policy` | `PricingPolicy` | Pricing policy |
| `sla_policy` | `SLAPolicy` | SLA policy |
---
## DeviceInfo
Hardware device information for a node.
| Field | Type | Description |
| --------- | ----------------- | ----------------------- |
| `vendor` | `string` | Vendor of the node |
| `storage` | `[]StorageDevice` | List of storage devices |
| `memory` | `[]MemoryDevice` | List of memory devices |
| `cpu` | `[]CPUDevice` | List of CPU devices |
| `gpu` | `[]GPUDevice` | List of GPU devices |
| `network` | `[]NetworkDevice` | List of network devices |
---
## StorageDevice
| Field | Type | Description |
| ------------- | -------- | --------------------- |
| `id` | `string` | Unique ID for device |
| `size_gb` | `f64` | Size in GB |
| `description` | `string` | Description of device |
---
## MemoryDevice
| Field | Type | Description |
| ------------- | -------- | --------------------- |
| `id` | `string` | Unique ID for device |
| `size_gb` | `f64` | Size in GB |
| `description` | `string` | Description of device |
---
## CPUDevice
| Field | Type | Description |
| ------------- | -------- | ------------------------ |
| `id` | `string` | Unique ID for device |
| `cores` | `int` | Number of CPU cores |
| `passmark` | `int` | Passmark benchmark score |
| `description` | `string` | Description of device |
| `cpu_brand` | `string` | Brand of the CPU |
| `cpu_version` | `string` | Version of the CPU |
---
## GPUDevice
| Field | Type | Description |
| ------------- | -------- | --------------------- |
| `id` | `string` | Unique ID for device |
| `cores` | `int` | Number of GPU cores |
| `memory_gb` | `f64` | GPU memory in GB |
| `description` | `string` | Description of device |
| `gpu_brand` | `string` | Brand of the GPU |
| `gpu_version` | `string` | Version of the GPU |
---
## NetworkDevice
| Field | Type | Description |
| ------------- | -------- | --------------------- |
| `id` | `string` | Unique ID for device |
| `speed_mbps` | `int` | Network speed in Mbps |
| `description` | `string` | Description of device |
---
## NodeCapacity
Aggregated hardware capacity for a node.
| Field | Type | Description |
| ------------ | ----- | ---------------------- |
| `storage_gb` | `f64` | Total storage in GB |
| `mem_gb` | `f64` | Total memory in GB |
| `mem_gb_gpu` | `f64` | Total GPU memory in GB |
| `passmark` | `int` | Total passmark score |
| `vcores` | `int` | Total virtual cores |
---
## SLAPolicy
Service Level Agreement policy for slices or node groups.
| Field | Type | Description |
| -------------------- | ----- | --------------------------------------- |
| `sla_uptime` | `int` | Required uptime % (e.g., 90) |
| `sla_bandwidth_mbit` | `int` | Guaranteed bandwidth in Mbps (0 = none) |
| `sla_penalty` | `int` | Penalty % if SLA is breached (0-100) |
---
## PricingPolicy
Pricing policy for slices or node groups.
| Field | Type | Description |
| ---------------------------- | ------- | --------------------------------------------------------- |
| `marketplace_year_discounts` | `[]int` | Discounts for 1Y, 2Y, 3Y prepaid usage (e.g. [30,40,50]) |
| `volume_discounts` | `[]int` | Volume discounts based on purchase size (e.g. [10,20,30]) |

View File

@@ -0,0 +1,37 @@
module datamodel
// I can bid for infra, and optionally get accepted
@[heap]
pub struct Bid {
pub mut:
id u32
customer_id u32 // links back to customer for this capacity (user on ledger)
compute_slices_nr int // nr of slices I need in 1 machine
compute_slice_price f64 // price per 1 GB slice I want to accept
storage_slices_nr int
storage_slice_price f64 // price per 1 GB storage slice I want to accept
storage_slices_nr int
status BidStatus
obligation bool // if obligation then will be charged and money needs to be in escrow, otherwise its an intent
start_date u32 // epoch
end_date u32
signature_user string // signature as done by a user/consumer to validate their identity and intent
billing_period BillingPeriod
}
pub enum BidStatus {
pending
confirmed
assigned
cancelled
done
}
pub enum BillingPeriod {
hourly
monthly
yearly
biannually
triannually
}

View File

@@ -0,0 +1,52 @@
module datamodel
// I can bid for infra, and optionally get accepted
@[heap]
pub struct Contract {
pub mut:
id u32
customer_id u32 // links back to customer for this capacity (user on ledger)
compute_slices []ComputeSliceProvisioned
storage_slices []StorageSliceProvisioned
compute_slice_price f64 // price per 1 GB agreed upon
storage_slice_price f64 // price per 1 GB agreed upon
network_slice_price f64 // price per 1 GB agreed upon (transfer)
status ContractStatus
start_date u32 // epoch
end_date u32
signature_user string // signature as done by a user/consumer to validate their identity and intent
signature_hoster string // signature as done by the hoster
billing_period BillingPeriod
}
pub enum ConctractStatus {
active
cancelled
error
paused
}
// typically 1GB of memory, but can be adjusted based based on size of machine
pub struct ComputeSliceProvisioned {
pub mut:
node_id u32
id u16 // the id of the slice in the node
mem_gb f64
storage_gb f64
passmark int
vcores int
cpu_oversubscription int
tags string
}
// 1GB of storage
pub struct StorageSliceProvisioned {
pub mut:
node_id u32
id u16 // the id of the slice in the node, are tracked in the node itself
storage_size_gb int
tags string
}

View File

@@ -0,0 +1,104 @@
module datamodel
//ACCESS ONLY TF
@[heap]
pub struct Node {
pub mut:
id int
nodegroupid int
uptime int // 0..100
computeslices []ComputeSlice
storageslices []StorageSlice
devices DeviceInfo
country string // 2 letter code as specified in lib/data/countries/data/countryInfo.txt, use that library for validation
capacity NodeCapacity // Hardware capacity details
birthtime u32 // first time node was active
pubkey string
signature_node string // signature done on node to validate pubkey with privkey
signature_farmer string // signature as done by farmers to validate their identity
}
pub struct DeviceInfo {
pub mut:
vendor string
storage []StorageDevice
memory []MemoryDevice
cpu []CPUDevice
gpu []GPUDevice
network []NetworkDevice
}
pub struct StorageDevice {
pub mut:
id string // can be used in node
size_gb f64 // Size of the storage device in gigabytes
description string // Description of the storage device
}
pub struct MemoryDevice {
pub mut:
id string // can be used in node
size_gb f64 // Size of the memory device in gigabytes
description string // Description of the memory device
}
pub struct CPUDevice {
pub mut:
id string // can be used in node
cores int // Number of CPU cores
passmark int
description string // Description of the CPU
cpu_brand string // Brand of the CPU
cpu_version string // Version of the CPU
}
pub struct GPUDevice {
pub mut:
id string // can be used in node
cores int // Number of GPU cores
memory_gb f64 // Size of the GPU memory in gigabytes
description string // Description of the GPU
gpu_brand string
gpu_version string
}
pub struct NetworkDevice {
pub mut:
id string // can be used in node
speed_mbps int // Network speed in Mbps
description string // Description of the network device
}
// NodeCapacity represents the hardware capacity details of a node.
pub struct NodeCapacity {
pub mut:
storage_gb f64 // Total storage in gigabytes
mem_gb f64 // Total memory in gigabytes
mem_gb_gpu f64 // Total GPU memory in gigabytes
passmark int // Passmark score for the node
vcores int // Total virtual cores
}
// typically 1GB of memory, but can be adjusted based based on size of machine
pub struct ComputeSlice {
pub mut:
u16 int // the id of the slice in the node
mem_gb f64
storage_gb f64
passmark int
vcores int
cpu_oversubscription int
storage_oversubscription int
gpus u8 // nr of GPU's see node to know what GPU's are
}
// 1GB of storage
pub struct StorageSlice {
pub mut:
u16 int // the id of the slice in the node, are tracked in the node itself
}
fn (mut n Node) check() ! {
// todo calculate NodeCapacity out of the devices on the Node
}

View File

@@ -0,0 +1,33 @@
module datamodel
// is a root object, is the only obj farmer needs to configure in the UI, this defines how slices will be created
@[heap]
pub struct NodeGroup {
pub mut:
id u32
farmerid u32 // link back to farmer who owns the nodegroup, is a user?
secret string // only visible by farmer, in future encrypted, used to boot a node
description string
slapolicy SLAPolicy
pricingpolicy PricingPolicy
compute_slice_normalized_pricing_cc f64 // pricing in CC - cloud credit, per 2GB node slice
storage_slice_normalized_pricing_cc f64 // pricing in CC - cloud credit, per 1GB storage slice
signature_farmer string // signature as done by farmers to validate that they created this group
}
pub struct SLAPolicy {
pub mut:
sla_uptime int // should +90
sla_bandwidth_mbit int // minimal mbits we can expect avg over 1h per node, 0 means we don't guarantee
sla_penalty int // 0-100, percent of money given back in relation to month if sla breached, e.g. 200 means we return 2 months worth of rev if sla missed
}
pub struct PricingPolicy {
pub mut:
marketplace_year_discounts []int = [30, 40, 50] // e.g. 30,40,50 means if user has more CC in wallet than 1 year utilization on all his purchaes then this provider gives 30%, 2Y 40%, ...
// volume_discounts []int = [10, 20, 30] // e.g. 10,20,30
}

View File

@@ -0,0 +1,19 @@
@[heap]
pub struct NodeGroupReputation {
pub mut:
nodegroup_id u32
reputation int = 50 // between 0 and 100, earned over time
uptime int // between 0 and 100, set by system, farmer has no ability to set this
nodes []NodeReputation
}
pub struct NodeReputation {
pub mut:
node_id u32
reputation int = 50 // between 0 and 100, earned over time
uptime int // between 0 and 100, set by system, farmer has no ability to set this
}