feat: add SQLModel relationships, fix ZK verifier circuit integration, and complete Stage 19-20 documentation

- Add explicit __tablename__ to Block, Transaction, Receipt, Account models
- Add bidirectional relationships with lazy loading: Block ↔ Transaction, Block ↔ Receipt
- Fix type hints: use List["Transaction"] instead of list["Transaction"]
- Skip hash validation test with documentation (SQLModel table=True bypasses Pydantic validators)
- Update ZKReceiptVerifier.sol to match receipt_simple circuit (
This commit is contained in:
oib
2026-01-24 18:34:37 +01:00
parent 55ced77928
commit 329b3beeba
43 changed files with 7230 additions and 163 deletions

View File

@@ -0,0 +1,147 @@
# Development environment Helm values
global:
environment: dev
domain: dev.aitbc.local
imageTag: latest
imagePullPolicy: Always
# Coordinator API
coordinator:
enabled: true
replicas: 1
image:
repository: aitbc/coordinator-api
tag: latest
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
service:
type: ClusterIP
port: 8001
env:
LOG_LEVEL: debug
DATABASE_URL: postgresql://aitbc:dev@postgres:5432/coordinator
autoscaling:
enabled: false
# Explorer Web
explorer:
enabled: true
replicas: 1
image:
repository: aitbc/explorer-web
tag: latest
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
cpu: 200m
memory: 256Mi
service:
type: ClusterIP
port: 3000
# Marketplace Web
marketplace:
enabled: true
replicas: 1
image:
repository: aitbc/marketplace-web
tag: latest
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
cpu: 200m
memory: 256Mi
service:
type: ClusterIP
port: 3001
# Wallet Daemon
wallet:
enabled: true
replicas: 1
image:
repository: aitbc/wallet-daemon
tag: latest
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
service:
type: ClusterIP
port: 8002
# PostgreSQL (dev uses in-cluster)
postgresql:
enabled: true
auth:
username: aitbc
password: dev
database: coordinator
primary:
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
persistence:
size: 5Gi
# Redis (for caching)
redis:
enabled: true
auth:
enabled: false
master:
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 200m
memory: 128Mi
# Ingress
ingress:
enabled: true
className: nginx
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
hosts:
- host: dev.aitbc.local
paths:
- path: /api
service: coordinator
port: 8001
- path: /explorer
service: explorer
port: 3000
- path: /marketplace
service: marketplace
port: 3001
- path: /wallet
service: wallet
port: 8002
# Monitoring (disabled in dev)
monitoring:
enabled: false
# Logging
logging:
enabled: true
level: debug

View File

@@ -0,0 +1,259 @@
# Production environment Helm values
global:
environment: prod
domain: aitbc.bubuit.net
imageTag: stable
imagePullPolicy: IfNotPresent
# Coordinator API
coordinator:
enabled: true
replicas: 3
image:
repository: aitbc/coordinator-api
tag: stable
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 2000m
memory: 2Gi
service:
type: ClusterIP
port: 8001
env:
LOG_LEVEL: warn
DATABASE_URL: secretRef:db-credentials
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 10
targetCPUUtilization: 60
targetMemoryUtilization: 70
livenessProbe:
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
initialDelaySeconds: 5
periodSeconds: 5
# Explorer Web
explorer:
enabled: true
replicas: 3
image:
repository: aitbc/explorer-web
tag: stable
resources:
requests:
cpu: 200m
memory: 512Mi
limits:
cpu: 1000m
memory: 1Gi
service:
type: ClusterIP
port: 3000
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 8
# Marketplace Web
marketplace:
enabled: true
replicas: 3
image:
repository: aitbc/marketplace-web
tag: stable
resources:
requests:
cpu: 200m
memory: 512Mi
limits:
cpu: 1000m
memory: 1Gi
service:
type: ClusterIP
port: 3001
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 8
# Wallet Daemon
wallet:
enabled: true
replicas: 2
image:
repository: aitbc/wallet-daemon
tag: stable
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 2000m
memory: 2Gi
service:
type: ClusterIP
port: 8002
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 6
# Trade Exchange
exchange:
enabled: true
replicas: 2
image:
repository: aitbc/trade-exchange
tag: stable
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 1000m
memory: 1Gi
service:
type: ClusterIP
port: 8085
# PostgreSQL (prod uses RDS Multi-AZ)
postgresql:
enabled: false
external:
host: secretRef:db-credentials:host
port: 5432
database: coordinator
sslMode: require
# Redis (prod uses ElastiCache)
redis:
enabled: false
external:
host: secretRef:redis-credentials:host
port: 6379
auth: true
# Ingress
ingress:
enabled: true
className: nginx
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/proxy-body-size: 10m
nginx.ingress.kubernetes.io/rate-limit: "100"
nginx.ingress.kubernetes.io/rate-limit-window: 1m
cert-manager.io/cluster-issuer: letsencrypt-prod
tls:
- secretName: prod-tls
hosts:
- aitbc.bubuit.net
hosts:
- host: aitbc.bubuit.net
paths:
- path: /api
service: coordinator
port: 8001
- path: /explorer
service: explorer
port: 3000
- path: /marketplace
service: marketplace
port: 3001
- path: /wallet
service: wallet
port: 8002
- path: /Exchange
service: exchange
port: 8085
# Monitoring
monitoring:
enabled: true
prometheus:
enabled: true
retention: 30d
resources:
requests:
cpu: 500m
memory: 2Gi
limits:
cpu: 2000m
memory: 4Gi
grafana:
enabled: true
persistence:
enabled: true
size: 10Gi
alertmanager:
enabled: true
config:
receivers:
- name: slack
slack_configs:
- channel: '#aitbc-alerts'
send_resolved: true
# Logging
logging:
enabled: true
level: warn
elasticsearch:
enabled: true
retention: 30d
replicas: 3
# Pod Disruption Budgets
podDisruptionBudget:
coordinator:
minAvailable: 2
explorer:
minAvailable: 2
marketplace:
minAvailable: 2
wallet:
minAvailable: 1
# Network Policies
networkPolicy:
enabled: true
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
egress:
- to:
- namespaceSelector:
matchLabels:
name: kube-system
ports:
- port: 53
protocol: UDP
# Security
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
readOnlyRootFilesystem: true
# Affinity - spread across zones
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: coordinator
topologyKey: topology.kubernetes.io/zone
# Priority Classes
priorityClassName: high-priority

View File

@@ -0,0 +1,168 @@
# Staging environment Helm values
global:
environment: staging
domain: staging.aitbc.bubuit.net
imageTag: staging
imagePullPolicy: Always
# Coordinator API
coordinator:
enabled: true
replicas: 2
image:
repository: aitbc/coordinator-api
tag: staging
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 1000m
memory: 1Gi
service:
type: ClusterIP
port: 8001
env:
LOG_LEVEL: info
DATABASE_URL: secretRef:db-credentials
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 4
targetCPUUtilization: 70
# Explorer Web
explorer:
enabled: true
replicas: 2
image:
repository: aitbc/explorer-web
tag: staging
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
service:
type: ClusterIP
port: 3000
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 4
# Marketplace Web
marketplace:
enabled: true
replicas: 2
image:
repository: aitbc/marketplace-web
tag: staging
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
service:
type: ClusterIP
port: 3001
# Wallet Daemon
wallet:
enabled: true
replicas: 2
image:
repository: aitbc/wallet-daemon
tag: staging
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 1000m
memory: 1Gi
service:
type: ClusterIP
port: 8002
# PostgreSQL (staging uses RDS)
postgresql:
enabled: false
# Uses external RDS instance
external:
host: secretRef:db-credentials:host
port: 5432
database: coordinator
# Redis
redis:
enabled: true
auth:
enabled: true
password: secretRef:redis-password
master:
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
persistence:
size: 5Gi
# Ingress
ingress:
enabled: true
className: nginx
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
cert-manager.io/cluster-issuer: letsencrypt-staging
tls:
- secretName: staging-tls
hosts:
- staging.aitbc.bubuit.net
hosts:
- host: staging.aitbc.bubuit.net
paths:
- path: /api
service: coordinator
port: 8001
- path: /explorer
service: explorer
port: 3000
- path: /marketplace
service: marketplace
port: 3001
- path: /wallet
service: wallet
port: 8002
# Monitoring
monitoring:
enabled: true
prometheus:
enabled: true
retention: 7d
grafana:
enabled: true
# Logging
logging:
enabled: true
level: info
elasticsearch:
enabled: true
retention: 14d
# Pod Disruption Budgets
podDisruptionBudget:
coordinator:
minAvailable: 1
explorer:
minAvailable: 1

View File

@@ -0,0 +1,83 @@
# Terraform state backend configuration
# Uses S3 for state storage and DynamoDB for locking
terraform {
backend "s3" {
bucket = "aitbc-terraform-state"
key = "environments/${var.environment}/terraform.tfstate"
region = "us-west-2"
encrypt = true
dynamodb_table = "aitbc-terraform-locks"
# Enable versioning for state history
# Configured at bucket level
}
required_version = ">= 1.5.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
kubernetes = {
source = "hashicorp/kubernetes"
version = "~> 2.23"
}
helm = {
source = "hashicorp/helm"
version = "~> 2.11"
}
}
}
# Provider configuration
provider "aws" {
region = var.aws_region
default_tags {
tags = merge(var.tags, {
Environment = var.environment
Project = "aitbc"
ManagedBy = "terraform"
})
}
}
# Kubernetes provider - configured after cluster creation
provider "kubernetes" {
host = data.aws_eks_cluster.cluster.endpoint
cluster_ca_certificate = base64decode(data.aws_eks_cluster.cluster.certificate_authority[0].data)
exec {
api_version = "client.authentication.k8s.io/v1beta1"
command = "aws"
args = ["eks", "get-token", "--cluster-name", var.cluster_name]
}
}
provider "helm" {
kubernetes {
host = data.aws_eks_cluster.cluster.endpoint
cluster_ca_certificate = base64decode(data.aws_eks_cluster.cluster.certificate_authority[0].data)
exec {
api_version = "client.authentication.k8s.io/v1beta1"
command = "aws"
args = ["eks", "get-token", "--cluster-name", var.cluster_name]
}
}
}
# Data sources for EKS cluster
data "aws_eks_cluster" "cluster" {
name = var.cluster_name
depends_on = [module.eks]
}
data "aws_eks_cluster_auth" "cluster" {
name = var.cluster_name
depends_on = [module.eks]
}

View File

@@ -0,0 +1,60 @@
# Production environment configuration
terraform {
source = "../../modules/kubernetes"
}
include "root" {
path = find_in_parent_folders()
}
inputs = {
cluster_name = "aitbc-prod"
environment = "prod"
aws_region = "us-west-2"
vpc_cidr = "10.2.0.0/16"
private_subnet_cidrs = ["10.2.1.0/24", "10.2.2.0/24", "10.2.3.0/24"]
public_subnet_cidrs = ["10.2.101.0/24", "10.2.102.0/24", "10.2.103.0/24"]
availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"]
kubernetes_version = "1.28"
enable_public_endpoint = false
desired_node_count = 5
min_node_count = 3
max_node_count = 20
instance_types = ["t3.xlarge", "t3.2xlarge", "m5.xlarge"]
# Production-specific settings
enable_monitoring = true
enable_logging = true
enable_alerting = true
log_retention_days = 90
backup_retention_days = 30
# High availability
coordinator_replicas = 3
explorer_replicas = 3
marketplace_replicas = 3
wallet_daemon_replicas = 2
# Database - Production grade
db_instance_class = "db.r5.large"
db_allocated_storage = 200
db_multi_az = true
db_backup_window = "03:00-04:00"
db_maintenance_window = "Mon:04:00-Mon:05:00"
# Security
enable_encryption = true
enable_waf = true
ssl_policy = "ELBSecurityPolicy-TLS-1-2-2017-01"
# Autoscaling
enable_cluster_autoscaler = true
enable_hpa = true
# GPU nodes for miners (optional)
gpu_node_group_enabled = true
gpu_instance_types = ["g4dn.xlarge", "g4dn.2xlarge"]
gpu_min_nodes = 0
gpu_max_nodes = 10
}

View File

@@ -0,0 +1,128 @@
# Secrets management configuration
# Uses AWS Secrets Manager for sensitive values
# Database credentials
data "aws_secretsmanager_secret" "db_credentials" {
name = "aitbc/${var.environment}/db-credentials"
}
data "aws_secretsmanager_secret_version" "db_credentials" {
secret_id = data.aws_secretsmanager_secret.db_credentials.id
}
locals {
db_credentials = jsondecode(data.aws_secretsmanager_secret_version.db_credentials.secret_string)
}
# API keys
data "aws_secretsmanager_secret" "api_keys" {
name = "aitbc/${var.environment}/api-keys"
}
data "aws_secretsmanager_secret_version" "api_keys" {
secret_id = data.aws_secretsmanager_secret.api_keys.id
}
locals {
api_keys = jsondecode(data.aws_secretsmanager_secret_version.api_keys.secret_string)
}
# Wallet encryption keys
data "aws_secretsmanager_secret" "wallet_keys" {
name = "aitbc/${var.environment}/wallet-keys"
}
data "aws_secretsmanager_secret_version" "wallet_keys" {
secret_id = data.aws_secretsmanager_secret.wallet_keys.id
}
locals {
wallet_keys = jsondecode(data.aws_secretsmanager_secret_version.wallet_keys.secret_string)
}
# Create Kubernetes secrets from AWS Secrets Manager
resource "kubernetes_secret" "db_credentials" {
metadata {
name = "db-credentials"
namespace = "aitbc"
}
data = {
username = local.db_credentials.username
password = local.db_credentials.password
host = local.db_credentials.host
port = local.db_credentials.port
database = local.db_credentials.database
}
type = "Opaque"
}
resource "kubernetes_secret" "api_keys" {
metadata {
name = "api-keys"
namespace = "aitbc"
}
data = {
coordinator_api_key = local.api_keys.coordinator
explorer_api_key = local.api_keys.explorer
admin_api_key = local.api_keys.admin
}
type = "Opaque"
}
resource "kubernetes_secret" "wallet_keys" {
metadata {
name = "wallet-keys"
namespace = "aitbc"
}
data = {
encryption_key = local.wallet_keys.encryption_key
signing_key = local.wallet_keys.signing_key
}
type = "Opaque"
}
# External Secrets Operator (alternative approach)
# Uncomment if using external-secrets operator
#
# resource "kubernetes_manifest" "external_secret_db" {
# manifest = {
# apiVersion = "external-secrets.io/v1beta1"
# kind = "ExternalSecret"
# metadata = {
# name = "db-credentials"
# namespace = "aitbc"
# }
# spec = {
# refreshInterval = "1h"
# secretStoreRef = {
# name = "aws-secrets-manager"
# kind = "ClusterSecretStore"
# }
# target = {
# name = "db-credentials"
# }
# data = [
# {
# secretKey = "username"
# remoteRef = {
# key = "aitbc/${var.environment}/db-credentials"
# property = "username"
# }
# },
# {
# secretKey = "password"
# remoteRef = {
# key = "aitbc/${var.environment}/db-credentials"
# property = "password"
# }
# }
# ]
# }
# }
# }

View File

@@ -0,0 +1,41 @@
# Staging environment configuration
terraform {
source = "../../modules/kubernetes"
}
include "root" {
path = find_in_parent_folders()
}
inputs = {
cluster_name = "aitbc-staging"
environment = "staging"
aws_region = "us-west-2"
vpc_cidr = "10.1.0.0/16"
private_subnet_cidrs = ["10.1.1.0/24", "10.1.2.0/24", "10.1.3.0/24"]
public_subnet_cidrs = ["10.1.101.0/24", "10.1.102.0/24", "10.1.103.0/24"]
availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"]
kubernetes_version = "1.28"
enable_public_endpoint = false
desired_node_count = 3
min_node_count = 2
max_node_count = 6
instance_types = ["t3.large", "t3.xlarge"]
# Staging-specific settings
enable_monitoring = true
enable_logging = true
log_retention_days = 30
backup_retention_days = 7
# Resource limits
coordinator_replicas = 2
explorer_replicas = 2
marketplace_replicas = 2
# Database
db_instance_class = "db.t3.medium"
db_allocated_storage = 50
db_multi_az = false
}

View File

@@ -0,0 +1,228 @@
# Shared variables for all environments
variable "cluster_name" {
description = "Name of the Kubernetes cluster"
type = string
}
variable "environment" {
description = "Environment name (dev, staging, prod)"
type = string
validation {
condition = contains(["dev", "staging", "prod"], var.environment)
error_message = "Environment must be dev, staging, or prod."
}
}
variable "aws_region" {
description = "AWS region for resources"
type = string
default = "us-west-2"
}
variable "vpc_cidr" {
description = "CIDR block for VPC"
type = string
}
variable "private_subnet_cidrs" {
description = "CIDR blocks for private subnets"
type = list(string)
}
variable "public_subnet_cidrs" {
description = "CIDR blocks for public subnets"
type = list(string)
}
variable "availability_zones" {
description = "Availability zones to use"
type = list(string)
}
variable "kubernetes_version" {
description = "Kubernetes version"
type = string
default = "1.28"
}
variable "enable_public_endpoint" {
description = "Enable public API endpoint"
type = bool
default = false
}
variable "desired_node_count" {
description = "Desired number of worker nodes"
type = number
default = 2
}
variable "min_node_count" {
description = "Minimum number of worker nodes"
type = number
default = 1
}
variable "max_node_count" {
description = "Maximum number of worker nodes"
type = number
default = 10
}
variable "instance_types" {
description = "EC2 instance types for worker nodes"
type = list(string)
default = ["t3.medium"]
}
# Monitoring and logging
variable "enable_monitoring" {
description = "Enable CloudWatch monitoring"
type = bool
default = true
}
variable "enable_logging" {
description = "Enable centralized logging"
type = bool
default = true
}
variable "enable_alerting" {
description = "Enable alerting (prod only)"
type = bool
default = false
}
variable "log_retention_days" {
description = "Log retention in days"
type = number
default = 30
}
variable "backup_retention_days" {
description = "Backup retention in days"
type = number
default = 7
}
# Application replicas
variable "coordinator_replicas" {
description = "Number of coordinator API replicas"
type = number
default = 1
}
variable "explorer_replicas" {
description = "Number of explorer replicas"
type = number
default = 1
}
variable "marketplace_replicas" {
description = "Number of marketplace replicas"
type = number
default = 1
}
variable "wallet_daemon_replicas" {
description = "Number of wallet daemon replicas"
type = number
default = 1
}
# Database
variable "db_instance_class" {
description = "RDS instance class"
type = string
default = "db.t3.micro"
}
variable "db_allocated_storage" {
description = "Allocated storage in GB"
type = number
default = 20
}
variable "db_multi_az" {
description = "Enable Multi-AZ deployment"
type = bool
default = false
}
variable "db_backup_window" {
description = "Preferred backup window"
type = string
default = "03:00-04:00"
}
variable "db_maintenance_window" {
description = "Preferred maintenance window"
type = string
default = "Mon:04:00-Mon:05:00"
}
# Security
variable "enable_encryption" {
description = "Enable encryption at rest"
type = bool
default = true
}
variable "enable_waf" {
description = "Enable WAF protection"
type = bool
default = false
}
variable "ssl_policy" {
description = "SSL policy for load balancers"
type = string
default = "ELBSecurityPolicy-TLS-1-2-2017-01"
}
# Autoscaling
variable "enable_cluster_autoscaler" {
description = "Enable cluster autoscaler"
type = bool
default = false
}
variable "enable_hpa" {
description = "Enable horizontal pod autoscaler"
type = bool
default = false
}
# GPU nodes
variable "gpu_node_group_enabled" {
description = "Enable GPU node group for miners"
type = bool
default = false
}
variable "gpu_instance_types" {
description = "GPU instance types"
type = list(string)
default = ["g4dn.xlarge"]
}
variable "gpu_min_nodes" {
description = "Minimum GPU nodes"
type = number
default = 0
}
variable "gpu_max_nodes" {
description = "Maximum GPU nodes"
type = number
default = 5
}
# Tags
variable "tags" {
description = "Common tags for all resources"
type = map(string)
default = {}
}