chore(systemd): remove obsolete systemd service files and update infrastructure documentation
- Remove 8 unused systemd service files from coordinator-api/systemd/ - aitbc-adaptive-learning.service (port 8005) - aitbc-advanced-ai.service - aitbc-enterprise-api.service - aitbc-gpu-multimodal.service (port 8003) - aitbc-marketplace-enhanced.service (port 8006) - aitbc-modality-optimization.service (port 8004) - aitbc-multimodal.service (port 8002) - aitbc-openclaw-enhanced.service (port 8007
This commit is contained in:
131
dev/examples/README.md
Normal file
131
dev/examples/README.md
Normal file
@@ -0,0 +1,131 @@
|
||||
# AITBC Local Simulation
|
||||
|
||||
Simulate client and GPU provider interactions with independent wallets and AITBC transactions.
|
||||
|
||||
## Structure
|
||||
|
||||
```
|
||||
home/
|
||||
├── genesis.py # Creates genesis block and distributes initial AITBC
|
||||
├── client/ # Customer/client wallet
|
||||
│ └── wallet.py # Client wallet management
|
||||
├── miner/ # GPU provider wallet
|
||||
│ └── wallet.py # Miner wallet management
|
||||
└── simulate.py # Complete workflow simulation
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
### 1. Initialize the Economy
|
||||
```bash
|
||||
cd /home/oib/windsurf/aitbc/home
|
||||
python3 genesis.py
|
||||
```
|
||||
This creates:
|
||||
- Genesis wallet: 1,000,000 AITBC
|
||||
- Client wallet: 10,000 AITBC
|
||||
- Miner wallet: 1,000 AITBC
|
||||
|
||||
### 2. Check Wallets
|
||||
```bash
|
||||
# Client wallet
|
||||
cd client && python3 wallet.py balance
|
||||
|
||||
# Miner wallet
|
||||
cd miner && python3 wallet.py balance
|
||||
```
|
||||
|
||||
### 3. Run Complete Simulation
|
||||
```bash
|
||||
cd /home/oib/windsurf/aitbc/home
|
||||
python3 simulate.py
|
||||
```
|
||||
|
||||
## Wallet Commands
|
||||
|
||||
### Client Wallet
|
||||
```bash
|
||||
cd client
|
||||
|
||||
# Check balance
|
||||
python3 wallet.py balance
|
||||
|
||||
# Show address
|
||||
python3 wallet.py address
|
||||
|
||||
# Pay for services
|
||||
python3 wallet.py send <amount> <address> <description>
|
||||
|
||||
# Transaction history
|
||||
python3 wallet.py history
|
||||
```
|
||||
|
||||
### Miner Wallet
|
||||
```bash
|
||||
cd miner
|
||||
|
||||
# Check balance with stats
|
||||
python3 wallet.py balance
|
||||
|
||||
# Add earnings from completed job
|
||||
python3 wallet.py earn <amount> --job <job_id> --desc "Service description"
|
||||
|
||||
# Withdraw earnings
|
||||
python3 wallet.py withdraw <amount> <address>
|
||||
|
||||
# Mining statistics
|
||||
python3 wallet.py stats
|
||||
```
|
||||
|
||||
## Example Workflow
|
||||
|
||||
### 1. Client Submits Job
|
||||
```bash
|
||||
cd /home/oib/windsurf/aitbc/cli
|
||||
python3 client.py submit inference --model llama-2-7b --prompt "What is AI?"
|
||||
```
|
||||
|
||||
### 2. Miner Processes Job
|
||||
```bash
|
||||
# Miner polls and gets job
|
||||
python3 miner.py poll
|
||||
|
||||
# Miner earns AITBC
|
||||
cd /home/oib/windsurf/aitbc/home/miner
|
||||
python3 wallet.py earn 50.0 --job abc123 --desc "Inference task"
|
||||
```
|
||||
|
||||
### 3. Client Pays
|
||||
```bash
|
||||
cd /home/oib/windsurf/aitbc/home/client
|
||||
|
||||
# Get miner address
|
||||
cd ../miner && python3 wallet.py address
|
||||
# Returns: aitbc1721d5bf8c0005ded6704
|
||||
|
||||
# Send payment
|
||||
cd ../client
|
||||
python3 wallet.py send 50.0 aitbc1721d5bf8c0005ded6704 "Payment for inference"
|
||||
```
|
||||
|
||||
## Wallet Files
|
||||
|
||||
- `client/client_wallet.json` - Client's wallet data
|
||||
- `miner/miner_wallet.json` - Miner's wallet data
|
||||
- `genesis_wallet.json` - Genesis wallet with remaining AITBC
|
||||
|
||||
## Integration with CLI Tools
|
||||
|
||||
The home wallets integrate with the CLI tools:
|
||||
|
||||
1. Submit jobs using `cli/client.py`
|
||||
2. Process jobs using `cli/miner.py`
|
||||
3. Track payments using `home/*/wallet.py`
|
||||
|
||||
## Tips
|
||||
|
||||
- Each wallet has a unique address
|
||||
- All transactions are recorded with timestamps
|
||||
- Genesis wallet holds the remaining AITBC supply
|
||||
- Use `simulate.py` for a complete demo
|
||||
- Check `wallet.py history` to see all transactions
|
||||
143
dev/examples/client_get_result.py
Executable file
143
dev/examples/client_get_result.py
Executable file
@@ -0,0 +1,143 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Client retrieves job result from completed GPU processing
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import json
|
||||
import sys
|
||||
import os
|
||||
|
||||
# Add paths
|
||||
sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'cli'))
|
||||
|
||||
def get_job_result(job_id):
|
||||
"""Get the result of a completed job"""
|
||||
|
||||
print(f"🔍 Retrieving result for job: {job_id}")
|
||||
print("=" * 60)
|
||||
|
||||
# Check job status
|
||||
print("\n1. Checking job status...")
|
||||
status_result = subprocess.run(
|
||||
f'cd ../cli && python3 client.py status {job_id}',
|
||||
shell=True,
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
|
||||
print(status_result.stdout)
|
||||
|
||||
# Check if job is completed
|
||||
if "completed" in status_result.stdout:
|
||||
print("\n2. ✅ Job completed! Retrieving result...")
|
||||
|
||||
# Parse the status to get result details
|
||||
# In a real implementation, this would fetch from the coordinator API
|
||||
print("\n📄 Job Result:")
|
||||
print("-" * 40)
|
||||
|
||||
# Simulate getting the result from the blockchain/coordinator
|
||||
print(f"Job ID: {job_id}")
|
||||
print("Status: Completed")
|
||||
print("Miner: ollama-miner")
|
||||
print("Model: llama3.2:latest")
|
||||
print("Processing Time: 2.3 seconds")
|
||||
print("\nOutput:")
|
||||
print("Hello! I'm an AI assistant powered by AITBC network.")
|
||||
print("I'm running on GPU infrastructure provided by network miners.")
|
||||
print("\nMetadata:")
|
||||
print("- Tokens processed: 15")
|
||||
print("- GPU utilization: 45%")
|
||||
print("- Cost: 0.000025 AITBC")
|
||||
|
||||
return True
|
||||
|
||||
elif "queued" in status_result.stdout:
|
||||
print("\n⏳ Job is still queued, waiting for miner...")
|
||||
return False
|
||||
|
||||
elif "running" in status_result.stdout:
|
||||
print("\n⚙️ Job is being processed by GPU provider...")
|
||||
return False
|
||||
|
||||
elif "failed" in status_result.stdout:
|
||||
print("\n❌ Job failed!")
|
||||
return False
|
||||
|
||||
else:
|
||||
print("\n❓ Unknown job status")
|
||||
return False
|
||||
|
||||
def watch_job(job_id):
|
||||
"""Watch a job until completion"""
|
||||
|
||||
print(f"👀 Watching job: {job_id}")
|
||||
print("=" * 60)
|
||||
|
||||
import time
|
||||
|
||||
max_wait = 60 # Maximum wait time in seconds
|
||||
start_time = time.time()
|
||||
|
||||
while time.time() - start_time < max_wait:
|
||||
print(f"\n⏰ Checking... ({int(time.time() - start_time)}s elapsed)")
|
||||
|
||||
# Get status
|
||||
result = subprocess.run(
|
||||
f'cd ../cli && python3 client.py status {job_id}',
|
||||
shell=True,
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
|
||||
if "completed" in result.stdout:
|
||||
print("\n✅ Job completed!")
|
||||
return get_job_result(job_id)
|
||||
elif "failed" in result.stdout:
|
||||
print("\n❌ Job failed!")
|
||||
return False
|
||||
|
||||
time.sleep(3)
|
||||
|
||||
print("\n⏰ Timeout waiting for job completion")
|
||||
return False
|
||||
|
||||
def list_recent_results():
|
||||
"""List recent completed jobs and their results"""
|
||||
|
||||
print("📋 Recent Job Results")
|
||||
print("=" * 60)
|
||||
|
||||
# Get recent blocks/jobs from explorer
|
||||
result = subprocess.run(
|
||||
'cd ../cli && python3 client.py blocks --limit 5',
|
||||
shell=True,
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
|
||||
print(result.stdout)
|
||||
|
||||
print("\n💡 To get specific result:")
|
||||
print(" python3 client_get_result.py <job_id>")
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 2:
|
||||
print("Usage:")
|
||||
print(" python3 client_get_result.py <job_id> # Get specific job result")
|
||||
print(" python3 client_get_result.py watch <job_id> # Watch job until complete")
|
||||
print(" python3 client_get_result.py list # List recent results")
|
||||
return
|
||||
|
||||
command = sys.argv[1]
|
||||
|
||||
if command == "list":
|
||||
list_recent_results()
|
||||
elif command == "watch" and len(sys.argv) > 2:
|
||||
watch_job(sys.argv[2])
|
||||
else:
|
||||
get_job_result(command)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
126
dev/examples/client_send_job.py
Executable file
126
dev/examples/client_send_job.py
Executable file
@@ -0,0 +1,126 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Client sends a job to GPU provider and pays for it
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import json
|
||||
import time
|
||||
import sys
|
||||
import os
|
||||
|
||||
# Add paths
|
||||
sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'cli'))
|
||||
sys.path.append(os.path.join(os.path.dirname(__file__)))
|
||||
|
||||
def send_job_to_gpu_provider():
|
||||
print("🚀 Client: Sending Job to GPU Provider")
|
||||
print("=" * 60)
|
||||
|
||||
# 1. Check client wallet balance
|
||||
print("\n1. Checking client wallet...")
|
||||
result = subprocess.run(
|
||||
'cd client && python3 wallet.py balance',
|
||||
shell=True,
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
print(result.stdout)
|
||||
|
||||
# 2. Submit job to coordinator
|
||||
print("\n2. Submitting 'hello' job to network...")
|
||||
job_result = subprocess.run(
|
||||
'cd ../cli && python3 client.py submit inference --prompt "hello"',
|
||||
shell=True,
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
|
||||
print(job_result.stdout)
|
||||
|
||||
# Extract job ID
|
||||
job_id = None
|
||||
if "Job ID:" in job_result.stdout:
|
||||
for line in job_result.stdout.split('\n'):
|
||||
if "Job ID:" in line:
|
||||
job_id = line.split()[-1]
|
||||
break
|
||||
|
||||
if not job_id:
|
||||
print("❌ Failed to submit job")
|
||||
return
|
||||
|
||||
print(f"\n✅ Job submitted: {job_id}")
|
||||
|
||||
# 3. Wait for miner to process
|
||||
print("\n3. Waiting for GPU provider to process job...")
|
||||
print(" (Make sure miner is running: python3 cli/miner.py mine)")
|
||||
|
||||
# Check job status
|
||||
max_wait = 30
|
||||
for i in range(max_wait):
|
||||
status_result = subprocess.run(
|
||||
f'cd ../cli && python3 client.py status {job_id}',
|
||||
shell=True,
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
|
||||
if "completed" in status_result.stdout:
|
||||
print("✅ Job completed by GPU provider!")
|
||||
print(status_result.stdout)
|
||||
break
|
||||
elif "failed" in status_result.stdout:
|
||||
print("❌ Job failed")
|
||||
print(status_result.stdout)
|
||||
break
|
||||
else:
|
||||
print(f" Waiting... ({i+1}s)")
|
||||
time.sleep(1)
|
||||
|
||||
# 4. Get cost and pay
|
||||
print("\n4. Processing payment...")
|
||||
|
||||
# For demo, assume cost is 10 AITBC
|
||||
job_cost = 10.0
|
||||
|
||||
# Get miner address
|
||||
miner_result = subprocess.run(
|
||||
'cd miner && python3 wallet.py address',
|
||||
shell=True,
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
|
||||
miner_address = None
|
||||
if "Miner Address:" in miner_result.stdout:
|
||||
for line in miner_result.stdout.split('\n'):
|
||||
if "Miner Address:" in line:
|
||||
miner_address = line.split()[-1]
|
||||
break
|
||||
|
||||
if miner_address:
|
||||
print(f" Paying {job_cost} AITBC to miner...")
|
||||
|
||||
# Send payment
|
||||
pay_result = subprocess.run(
|
||||
f'cd client && python3 wallet.py send {job_cost} {miner_address} "Payment for job {job_id}"',
|
||||
shell=True,
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
|
||||
print(pay_result.stdout)
|
||||
|
||||
# 5. Show final balances
|
||||
print("\n5. Final balances:")
|
||||
print("\n Client:")
|
||||
subprocess.run('cd client && python3 wallet.py balance', shell=True)
|
||||
|
||||
print("\n Miner:")
|
||||
subprocess.run('cd miner && python3 wallet.py balance', shell=True)
|
||||
|
||||
print("\n✅ Job completed and paid for!")
|
||||
|
||||
if __name__ == "__main__":
|
||||
send_job_to_gpu_provider()
|
||||
74
dev/examples/client_wallet.py
Executable file
74
dev/examples/client_wallet.py
Executable file
@@ -0,0 +1,74 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Client wallet for managing AITBC tokens
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from datetime import datetime
|
||||
|
||||
# Add parent directory to path to import wallet module
|
||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
import importlib.util
|
||||
spec = importlib.util.spec_from_file_location("wallet", os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "wallet.py"))
|
||||
wallet = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(wallet)
|
||||
AITBCWallet = wallet.AITBCWallet
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Client Wallet - Manage AITBC for paying for GPU services")
|
||||
parser.add_argument("--wallet", default="client_wallet.json", help="Wallet file name")
|
||||
|
||||
subparsers = parser.add_subparsers(dest="command", help="Commands")
|
||||
|
||||
# Balance command
|
||||
balance_parser = subparsers.add_parser("balance", help="Show balance")
|
||||
|
||||
# Address command
|
||||
address_parser = subparsers.add_parser("address", help="Show wallet address")
|
||||
|
||||
# History command
|
||||
history_parser = subparsers.add_parser("history", help="Show transaction history")
|
||||
|
||||
# Send command (pay for services)
|
||||
send_parser = subparsers.add_parser("send", help="Send AITBC to GPU provider")
|
||||
send_parser.add_argument("amount", type=float, help="Amount to send")
|
||||
send_parser.add_argument("to", help="Recipient address")
|
||||
send_parser.add_argument("description", help="Payment description")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if not args.command:
|
||||
parser.print_help()
|
||||
return
|
||||
|
||||
# Use client-specific wallet directory
|
||||
wallet_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
wallet_path = os.path.join(wallet_dir, args.wallet)
|
||||
|
||||
wallet = AITBCWallet(wallet_path)
|
||||
|
||||
if args.command == "balance":
|
||||
print("💼 CLIENT WALLET")
|
||||
print("=" * 40)
|
||||
wallet.show_balance()
|
||||
print("\n💡 Use 'send' to pay for GPU services")
|
||||
|
||||
elif args.command == "address":
|
||||
print(f"💼 Client Address: {wallet.data['address']}")
|
||||
print(" Share this address to receive AITBC")
|
||||
|
||||
elif args.command == "history":
|
||||
print("💼 CLIENT TRANSACTION HISTORY")
|
||||
print("=" * 40)
|
||||
wallet.show_history()
|
||||
|
||||
elif args.command == "send":
|
||||
print(f"💸 Sending {args.amount} AITBC to {args.to}")
|
||||
print(f" For: {args.description}")
|
||||
wallet.spend(args.amount, args.description)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
199
dev/examples/enhanced_client.py
Executable file
199
dev/examples/enhanced_client.py
Executable file
@@ -0,0 +1,199 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Enhanced client that submits jobs and automatically retrieves results
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import json
|
||||
import time
|
||||
import sys
|
||||
import os
|
||||
|
||||
# Add paths
|
||||
sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'cli'))
|
||||
|
||||
class AITBCClient:
|
||||
def __init__(self):
|
||||
self.coordinator_url = "http://localhost:8001"
|
||||
self.api_key = "${CLIENT_API_KEY}"
|
||||
|
||||
def submit_job(self, prompt, model="llama3.2:latest", wait_for_result=True):
|
||||
"""Submit a job and optionally wait for result"""
|
||||
|
||||
print(f"📤 Submitting job to AITBC network...")
|
||||
print(f" Prompt: '{prompt}'")
|
||||
print(f" Model: {model}")
|
||||
print()
|
||||
|
||||
# Submit job
|
||||
result = subprocess.run(
|
||||
f'cd ../cli && python3 client.py submit inference --prompt "{prompt}"',
|
||||
shell=True,
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
|
||||
# Extract job ID
|
||||
job_id = None
|
||||
for line in result.stdout.split('\n'):
|
||||
if "Job ID:" in line:
|
||||
job_id = line.split()[-1]
|
||||
break
|
||||
|
||||
if not job_id:
|
||||
print("❌ Failed to submit job")
|
||||
return None
|
||||
|
||||
print(f"✅ Job submitted: {job_id}")
|
||||
|
||||
if wait_for_result:
|
||||
return self.wait_for_result(job_id)
|
||||
else:
|
||||
return job_id
|
||||
|
||||
def wait_for_result(self, job_id, timeout=60):
|
||||
"""Wait for job completion and return result"""
|
||||
|
||||
print(f"⏳ Waiting for GPU provider to process job...")
|
||||
print(f" Timeout: {timeout}s")
|
||||
print()
|
||||
|
||||
start_time = time.time()
|
||||
|
||||
while time.time() - start_time < timeout:
|
||||
# Check status
|
||||
status_result = subprocess.run(
|
||||
f'cd ../cli && python3 client.py status {job_id}',
|
||||
shell=True,
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
|
||||
if "completed" in status_result.stdout:
|
||||
print(f"✅ Job completed by GPU provider!")
|
||||
print()
|
||||
return self.get_result(job_id)
|
||||
elif "failed" in status_result.stdout:
|
||||
print(f"❌ Job failed")
|
||||
return None
|
||||
elif "running" in status_result.stdout:
|
||||
elapsed = int(time.time() - start_time)
|
||||
print(f" ⚙️ Processing... ({elapsed}s)")
|
||||
else:
|
||||
elapsed = int(time.time() - start_time)
|
||||
print(f" ⏳ Waiting in queue... ({elapsed}s)")
|
||||
|
||||
time.sleep(3)
|
||||
|
||||
print(f"⏰ Timeout after {timeout}s")
|
||||
return None
|
||||
|
||||
def get_result(self, job_id):
|
||||
"""Get and display job result"""
|
||||
|
||||
print(f"📄 Job Result for {job_id}")
|
||||
print("=" * 60)
|
||||
|
||||
# In a real implementation, fetch from coordinator API
|
||||
# For now, simulate the result
|
||||
|
||||
# Get job details
|
||||
status_result = subprocess.run(
|
||||
f'cd ../cli && python3 client.py status {job_id}',
|
||||
shell=True,
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
|
||||
print("Job Details:")
|
||||
print(status_result.stdout)
|
||||
|
||||
print("\nGenerated Output:")
|
||||
print("-" * 40)
|
||||
|
||||
# Simulate different outputs based on job
|
||||
if "hello" in job_id.lower():
|
||||
print("Hello! 👋")
|
||||
print("I'm an AI assistant running on the AITBC network.")
|
||||
print("Your request was processed by a GPU miner in the network.")
|
||||
elif "blockchain" in job_id.lower():
|
||||
print("Blockchain is a distributed ledger technology that maintains")
|
||||
print("a secure and decentralized record of transactions across multiple")
|
||||
print("computers. It's the foundation of cryptocurrencies like Bitcoin")
|
||||
print("and has many other applications beyond digital currencies.")
|
||||
else:
|
||||
print("This is a sample response from the AITBC network.")
|
||||
print("The actual output would be generated by the GPU provider")
|
||||
print("based on your specific prompt and requirements.")
|
||||
|
||||
print("\nProcessing Details:")
|
||||
print("-" * 40)
|
||||
print(f"• Miner: GPU Provider")
|
||||
print(f"• Model: llama3.2:latest")
|
||||
print(f"• Tokens: ~25")
|
||||
print(f"• Cost: 0.000025 AITBC")
|
||||
print(f"• Network: AITBC")
|
||||
|
||||
return {
|
||||
"job_id": job_id,
|
||||
"status": "completed",
|
||||
"output": "Generated response from GPU provider"
|
||||
}
|
||||
|
||||
def pay_for_job(self, job_id, amount=25.0):
|
||||
"""Pay for a completed job"""
|
||||
|
||||
print(f"\n💸 Paying for job {job_id}...")
|
||||
|
||||
# Get miner address
|
||||
miner_result = subprocess.run(
|
||||
'cd miner && python3 wallet.py address',
|
||||
shell=True,
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
|
||||
miner_address = None
|
||||
for line in miner_result.stdout.split('\n'):
|
||||
if "Miner Address:" in line:
|
||||
miner_address = line.split()[-1]
|
||||
break
|
||||
|
||||
if miner_address:
|
||||
# Send payment
|
||||
pay_result = subprocess.run(
|
||||
f'cd client && python3 wallet.py send {amount} {miner_address} "Payment for job {job_id}"',
|
||||
shell=True,
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
|
||||
print(pay_result.stdout)
|
||||
return True
|
||||
else:
|
||||
print("❌ Could not get miner address")
|
||||
return False
|
||||
|
||||
def main():
|
||||
client = AITBCClient()
|
||||
|
||||
print("🚀 AITBC Enhanced Client")
|
||||
print("=" * 60)
|
||||
|
||||
# Example 1: Submit and wait for result
|
||||
print("\n📝 Example 1: Submit job and wait for result")
|
||||
print("-" * 40)
|
||||
|
||||
result = client.submit_job("hello", wait_for_result=True)
|
||||
|
||||
if result:
|
||||
# Pay for the job
|
||||
client.pay_for_job(result["job_id"])
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("✅ Complete workflow demonstrated!")
|
||||
print("\n💡 To use with your own prompt:")
|
||||
print(" python3 enhanced_client.py")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
109
dev/examples/example_client_remote.py
Normal file
109
dev/examples/example_client_remote.py
Normal file
@@ -0,0 +1,109 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Example client using the remote AITBC coordinator
|
||||
"""
|
||||
|
||||
import httpx
|
||||
import json
|
||||
from datetime import datetime
|
||||
|
||||
# Configuration - using the SSH tunnel to remote server
|
||||
COORDINATOR_URL = "http://localhost:8001"
|
||||
CLIENT_API_KEY = "${CLIENT_API_KEY}"
|
||||
|
||||
def create_job():
|
||||
"""Create a job on the remote coordinator"""
|
||||
job_data = {
|
||||
"payload": {
|
||||
"type": "inference",
|
||||
"task": "text-generation",
|
||||
"model": "llama-2-7b",
|
||||
"parameters": {
|
||||
"prompt": "Hello, AITBC!",
|
||||
"max_tokens": 100
|
||||
}
|
||||
},
|
||||
"ttl_seconds": 900
|
||||
}
|
||||
|
||||
with httpx.Client() as client:
|
||||
response = client.post(
|
||||
f"{COORDINATOR_URL}/v1/jobs",
|
||||
headers={
|
||||
"Content-Type": "application/json",
|
||||
"X-Api-Key": CLIENT_API_KEY
|
||||
},
|
||||
json=job_data
|
||||
)
|
||||
|
||||
if response.status_code == 201:
|
||||
job = response.json()
|
||||
print(f"✅ Job created successfully!")
|
||||
print(f" Job ID: {job['job_id']}")
|
||||
print(f" State: {job['state']}")
|
||||
print(f" Expires at: {job['expires_at']}")
|
||||
return job['job_id']
|
||||
else:
|
||||
print(f"❌ Failed to create job: {response.status_code}")
|
||||
print(f" Response: {response.text}")
|
||||
return None
|
||||
|
||||
def check_job_status(job_id):
|
||||
"""Check the status of a job"""
|
||||
with httpx.Client() as client:
|
||||
response = client.get(
|
||||
f"{COORDINATOR_URL}/v1/jobs/{job_id}",
|
||||
headers={"X-Api-Key": CLIENT_API_KEY}
|
||||
)
|
||||
|
||||
if response.status_code == 200:
|
||||
job = response.json()
|
||||
print(f"\n📊 Job Status:")
|
||||
print(f" Job ID: {job['job_id']}")
|
||||
print(f" State: {job['state']}")
|
||||
print(f" Assigned Miner: {job.get('assigned_miner_id', 'None')}")
|
||||
print(f" Created: {job['requested_at']}")
|
||||
return job
|
||||
else:
|
||||
print(f"❌ Failed to get job status: {response.status_code}")
|
||||
return None
|
||||
|
||||
def list_blocks():
|
||||
"""List blocks from the explorer"""
|
||||
with httpx.Client() as client:
|
||||
response = client.get(f"{COORDINATOR_URL}/v1/explorer/blocks")
|
||||
|
||||
if response.status_code == 200:
|
||||
blocks = response.json()
|
||||
print(f"\n📦 Recent Blocks ({len(blocks['items'])} total):")
|
||||
for block in blocks['items'][:5]: # Show last 5 blocks
|
||||
print(f" Height: {block['height']}")
|
||||
print(f" Hash: {block['hash']}")
|
||||
print(f" Time: {block['timestamp']}")
|
||||
print(f" Transactions: {block['txCount']}")
|
||||
print(f" Proposer: {block['proposer']}")
|
||||
print()
|
||||
else:
|
||||
print(f"❌ Failed to list blocks: {response.status_code}")
|
||||
|
||||
def main():
|
||||
print("🚀 AITBC Remote Client Example")
|
||||
print(f" Connecting to: {COORDINATOR_URL}")
|
||||
print()
|
||||
|
||||
# List current blocks
|
||||
list_blocks()
|
||||
|
||||
# Create a new job
|
||||
job_id = create_job()
|
||||
|
||||
if job_id:
|
||||
# Check job status
|
||||
check_job_status(job_id)
|
||||
|
||||
# List blocks again to see the new job
|
||||
print("\n🔄 Updated block list:")
|
||||
list_blocks()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
85
dev/examples/genesis.py
Executable file
85
dev/examples/genesis.py
Executable file
@@ -0,0 +1,85 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Genesis wallet - Distributes initial AITBC from genesis block
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
from datetime import datetime
|
||||
|
||||
# Add parent directory to path
|
||||
sys.path.append(os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'cli'))
|
||||
from wallet import AITBCWallet
|
||||
|
||||
def main():
|
||||
print("🌍 GENESIS BLOCK - Initial AITBC Distribution")
|
||||
print("=" * 60)
|
||||
|
||||
# Create genesis wallet with large initial balance
|
||||
genesis = AITBCWallet("genesis_wallet.json")
|
||||
genesis.data["balance"] = 1000000.0 # 1 million AITBC
|
||||
genesis.data["transactions"] = [{
|
||||
"type": "genesis",
|
||||
"amount": 1000000.0,
|
||||
"description": "Genesis block creation",
|
||||
"timestamp": datetime.now().isoformat()
|
||||
}]
|
||||
genesis.save()
|
||||
|
||||
print(f"💰 Genesis Wallet Created")
|
||||
print(f" Address: {genesis.data['address']}")
|
||||
print(f" Balance: {genesis.data['balance']} AITBC")
|
||||
print()
|
||||
|
||||
# Distribute to client and miner
|
||||
client_wallet = AITBCWallet(os.path.join("client", "client_wallet.json"))
|
||||
miner_wallet = AITBCWallet(os.path.join("miner", "miner_wallet.json"))
|
||||
|
||||
print("📤 Distributing Initial AITBC")
|
||||
print("-" * 40)
|
||||
|
||||
# Give client 10,000 AITBC to spend
|
||||
client_address = client_wallet.data["address"]
|
||||
print(f"💸 Sending 10,000 AITBC to Client ({client_address[:20]}...)")
|
||||
client_wallet.add_earnings(10000.0, "genesis_distribution", "Initial funding from genesis block")
|
||||
|
||||
# Give miner 1,000 AITBC to start
|
||||
miner_address = miner_wallet.data["address"]
|
||||
print(f"💸 Sending 1,000 AITBC to Miner ({miner_address[:20]}...)")
|
||||
miner_wallet.add_earnings(1000.0, "genesis_distribution", "Initial funding from genesis block")
|
||||
|
||||
# Update genesis wallet
|
||||
genesis.data["balance"] -= 11000.0
|
||||
genesis.data["transactions"].extend([
|
||||
{
|
||||
"type": "transfer",
|
||||
"amount": -10000.0,
|
||||
"to": client_address,
|
||||
"description": "Initial client funding",
|
||||
"timestamp": datetime.now().isoformat()
|
||||
},
|
||||
{
|
||||
"type": "transfer",
|
||||
"amount": -1000.0,
|
||||
"to": miner_address,
|
||||
"description": "Initial miner funding",
|
||||
"timestamp": datetime.now().isoformat()
|
||||
}
|
||||
])
|
||||
genesis.save()
|
||||
|
||||
print()
|
||||
print("✅ Distribution Complete!")
|
||||
print("=" * 60)
|
||||
print(f"Genesis Balance: {genesis.data['balance']} AITBC")
|
||||
print(f"Client Balance: {client_wallet.data['balance']} AITBC")
|
||||
print(f"Miner Balance: {miner_wallet.data['balance']} AITBC")
|
||||
print()
|
||||
print("💡 Next Steps:")
|
||||
print(" 1. Client: Submit jobs and pay for GPU services")
|
||||
print(" 2. Miner: Process jobs and earn AITBC")
|
||||
print(" 3. Track everything with the wallet CLI tools")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
144
dev/examples/how_customer_gets_reply.py
Executable file
144
dev/examples/how_customer_gets_reply.py
Executable file
@@ -0,0 +1,144 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Demonstration: How customers get replies from GPU providers
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import time
|
||||
|
||||
def main():
|
||||
print("📨 How Customers Get Replies in AITBC")
|
||||
print("=" * 60)
|
||||
|
||||
print("\n🔄 Complete Flow:")
|
||||
print("1. Customer submits job")
|
||||
print("2. GPU provider processes job")
|
||||
print("3. Result stored on blockchain")
|
||||
print("4. Customer retrieves result")
|
||||
print("5. Customer pays for service")
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("\n📝 STEP 1: Customer Submits Job")
|
||||
print("-" * 40)
|
||||
|
||||
# Submit a job
|
||||
result = subprocess.run(
|
||||
'cd ../cli && python3 client.py submit inference --prompt "What is AI?"',
|
||||
shell=True,
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
|
||||
print(result.stdout)
|
||||
|
||||
# Extract job ID
|
||||
job_id = None
|
||||
for line in result.stdout.split('\n'):
|
||||
if "Job ID:" in line:
|
||||
job_id = line.split()[-1]
|
||||
break
|
||||
|
||||
if not job_id:
|
||||
print("❌ Failed to submit job")
|
||||
return
|
||||
|
||||
print(f"\n✅ Job submitted with ID: {job_id}")
|
||||
|
||||
print("\n⚙️ STEP 2: GPU Provider Processes Job")
|
||||
print("-" * 40)
|
||||
print(" • Miner polls for jobs")
|
||||
print(" • Job assigned to miner")
|
||||
print(" • GPU processes the request")
|
||||
print(" • Result submitted to network")
|
||||
|
||||
# Simulate processing
|
||||
print("\n 💭 Simulating GPU processing...")
|
||||
time.sleep(2)
|
||||
|
||||
print("\n📦 STEP 3: Result Stored on Blockchain")
|
||||
print("-" * 40)
|
||||
print(f" • Job {job_id} marked as completed")
|
||||
print(f" • Result stored with job metadata")
|
||||
print(f" • Block created with job details")
|
||||
|
||||
# Show block
|
||||
print("\n 📋 Blockchain Entry:")
|
||||
print(f" Block Hash: {job_id}")
|
||||
print(f" Proposer: gpu-miner")
|
||||
print(f" Status: COMPLETED")
|
||||
print(f" Result: Available for retrieval")
|
||||
|
||||
print("\n🔍 STEP 4: Customer Retrieves Result")
|
||||
print("-" * 40)
|
||||
|
||||
print(" Method 1: Check job status")
|
||||
print(f" $ python3 cli/client.py status {job_id}")
|
||||
print()
|
||||
|
||||
# Show status
|
||||
status_result = subprocess.run(
|
||||
f'cd ../cli && python3 client.py status {job_id}',
|
||||
shell=True,
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
|
||||
print(" Status Result:")
|
||||
for line in status_result.stdout.split('\n'):
|
||||
if line.strip():
|
||||
print(f" {line}")
|
||||
|
||||
print("\n Method 2: Get full result")
|
||||
print(f" $ python3 client_get_result.py {job_id}")
|
||||
print()
|
||||
|
||||
print(" 📄 Full Result:")
|
||||
print(" ----------")
|
||||
print(" Output: AI stands for Artificial Intelligence, which refers")
|
||||
print(" to the simulation of human intelligence in machines")
|
||||
print(" that are programmed to think and learn.")
|
||||
print(" Tokens: 28")
|
||||
print(" Cost: 0.000028 AITBC")
|
||||
print(" Miner: GPU Provider #1")
|
||||
|
||||
print("\n💸 STEP 5: Customer Pays for Service")
|
||||
print("-" * 40)
|
||||
|
||||
# Get miner address
|
||||
miner_result = subprocess.run(
|
||||
'cd miner && python3 wallet.py address',
|
||||
shell=True,
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
|
||||
miner_address = None
|
||||
for line in miner_result.stdout.split('\n'):
|
||||
if "Miner Address:" in line:
|
||||
miner_address = line.split()[-1]
|
||||
break
|
||||
|
||||
if miner_address:
|
||||
print(f" Payment sent to: {miner_address}")
|
||||
print(" Amount: 25.0 AITBC")
|
||||
print(" Status: ✅ Paid")
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("✅ Customer successfully received reply!")
|
||||
|
||||
print("\n📋 Summary of Retrieval Methods:")
|
||||
print("-" * 40)
|
||||
print("1. Job Status: python3 cli/client.py status <job_id>")
|
||||
print("2. Full Result: python3 client_get_result.py <job_id>")
|
||||
print("3. Watch Job: python3 client_get_result.py watch <job_id>")
|
||||
print("4. List Recent: python3 client_get_result.py list")
|
||||
print("5. Enhanced Client: python3 enhanced_client.py")
|
||||
|
||||
print("\n💡 In production:")
|
||||
print(" • Results are stored on-chain")
|
||||
print(" • Customers can retrieve anytime")
|
||||
print(" • Results are immutable and verifiable")
|
||||
print(" • Payment is required to unlock full results")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
113
dev/examples/miner_wallet.py
Executable file
113
dev/examples/miner_wallet.py
Executable file
@@ -0,0 +1,113 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
GPU Provider wallet for managing earnings from mining
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from datetime import datetime
|
||||
|
||||
# Add parent directory to path to import wallet module
|
||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
import importlib.util
|
||||
spec = importlib.util.spec_from_file_location("wallet", os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "wallet.py"))
|
||||
wallet = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(wallet)
|
||||
AITBCWallet = wallet.AITBCWallet
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="GPU Provider Wallet - Manage earnings from mining services")
|
||||
parser.add_argument("--wallet", default="miner_wallet.json", help="Wallet file name")
|
||||
|
||||
subparsers = parser.add_subparsers(dest="command", help="Commands")
|
||||
|
||||
# Balance command
|
||||
balance_parser = subparsers.add_parser("balance", help="Show balance")
|
||||
|
||||
# Address command
|
||||
address_parser = subparsers.add_parser("address", help="Show wallet address")
|
||||
|
||||
# History command
|
||||
history_parser = subparsers.add_parser("history", help="Show transaction history")
|
||||
|
||||
# Earn command (receive payment for completed jobs)
|
||||
earn_parser = subparsers.add_parser("earn", help="Add earnings from completed job")
|
||||
earn_parser.add_argument("amount", type=float, help="Amount earned")
|
||||
earn_parser.add_argument("--job", required=True, help="Job ID that was completed")
|
||||
earn_parser.add_argument("--desc", default="GPU computation", help="Service description")
|
||||
|
||||
# Withdraw command
|
||||
withdraw_parser = subparsers.add_parser("withdraw", help="Withdraw AITBC to external wallet")
|
||||
withdraw_parser.add_argument("amount", type=float, help="Amount to withdraw")
|
||||
withdraw_parser.add_argument("address", help="Destination address")
|
||||
|
||||
# Stats command
|
||||
stats_parser = subparsers.add_parser("stats", help="Show mining statistics")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if not args.command:
|
||||
parser.print_help()
|
||||
return
|
||||
|
||||
# Use miner-specific wallet directory
|
||||
wallet_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
wallet_path = os.path.join(wallet_dir, args.wallet)
|
||||
|
||||
wallet = AITBCWallet(wallet_path)
|
||||
|
||||
if args.command == "balance":
|
||||
print("⛏️ GPU PROVIDER WALLET")
|
||||
print("=" * 40)
|
||||
wallet.show_balance()
|
||||
|
||||
# Show additional stats
|
||||
earnings = sum(t['amount'] for t in wallet.data['transactions'] if t['type'] == 'earn')
|
||||
jobs_completed = sum(1 for t in wallet.data['transactions'] if t['type'] == 'earn')
|
||||
print(f"\n📊 Mining Stats:")
|
||||
print(f" Total Earned: {earnings} AITBC")
|
||||
print(f" Jobs Completed: {jobs_completed}")
|
||||
print(f" Average per Job: {earnings/jobs_completed if jobs_completed > 0 else 0} AITBC")
|
||||
|
||||
elif args.command == "address":
|
||||
print(f"⛏️ Miner Address: {wallet.data['address']}")
|
||||
print(" Share this address to receive payments")
|
||||
|
||||
elif args.command == "history":
|
||||
print("⛏️ MINER TRANSACTION HISTORY")
|
||||
print("=" * 40)
|
||||
wallet.show_history()
|
||||
|
||||
elif args.command == "earn":
|
||||
print(f"💰 Adding earnings for job {args.job}")
|
||||
wallet.add_earnings(args.amount, args.job, args.desc)
|
||||
|
||||
elif args.command == "withdraw":
|
||||
print(f"💸 Withdrawing {args.amount} AITBC to {args.address}")
|
||||
wallet.spend(args.amount, f"Withdrawal to {args.address}")
|
||||
|
||||
elif args.command == "stats":
|
||||
print("⛏️ MINING STATISTICS")
|
||||
print("=" * 40)
|
||||
|
||||
transactions = wallet.data['transactions']
|
||||
earnings = [t for t in transactions if t['type'] == 'earn']
|
||||
spends = [t for t in transactions if t['type'] == 'spend']
|
||||
|
||||
total_earned = sum(t['amount'] for t in earnings)
|
||||
total_spent = sum(t['amount'] for t in spends)
|
||||
|
||||
print(f"💰 Total Earned: {total_earned} AITBC")
|
||||
print(f"💸 Total Spent: {total_spent} AITBC")
|
||||
print(f"💳 Net Balance: {wallet.data['balance']} AITBC")
|
||||
print(f"📊 Jobs Completed: {len(earnings)}")
|
||||
|
||||
if earnings:
|
||||
print(f"\n📈 Recent Earnings:")
|
||||
for earning in earnings[-5:]:
|
||||
print(f" +{earning['amount']} AITBC | Job: {earning.get('job_id', 'N/A')}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
265
dev/examples/python_313_features.py
Normal file
265
dev/examples/python_313_features.py
Normal file
@@ -0,0 +1,265 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Python 3.13.5 Features Demonstration for AITBC
|
||||
|
||||
This script showcases the new features and improvements available in Python 3.13.5
|
||||
that can benefit the AITBC project.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import time
|
||||
import asyncio
|
||||
from typing import Generic, TypeVar, override, List, Optional
|
||||
from pathlib import Path
|
||||
|
||||
print(f"🚀 Python 3.13.5 Features Demo - Running on Python {sys.version}")
|
||||
print("=" * 60)
|
||||
|
||||
# ============================================================================
|
||||
# 1. Enhanced Error Messages
|
||||
# ============================================================================
|
||||
|
||||
def demonstrate_enhanced_errors():
|
||||
"""Demonstrate improved error messages in Python 3.13"""
|
||||
print("\n1. Enhanced Error Messages:")
|
||||
print("-" * 30)
|
||||
|
||||
try:
|
||||
# This will show a much clearer error message in Python 3.13
|
||||
data = {"name": "AITBC", "version": "1.0"}
|
||||
result = data["missing_key"]
|
||||
except KeyError as e:
|
||||
print(f"KeyError: {e}")
|
||||
print("✅ Clearer error messages with exact location and suggestions")
|
||||
|
||||
# ============================================================================
|
||||
# 2. Type Parameter Defaults
|
||||
# ============================================================================
|
||||
|
||||
T = TypeVar('T')
|
||||
|
||||
class DataContainer(Generic[T]):
|
||||
"""Generic container with type parameter defaults (Python 3.13+)"""
|
||||
|
||||
def __init__(self, items: List[T] | None = None) -> None:
|
||||
# Type parameter defaults allow more flexible generic classes
|
||||
self.items = items or []
|
||||
|
||||
def add_item(self, item: T) -> None:
|
||||
self.items.append(item)
|
||||
|
||||
def get_items(self) -> List[T]:
|
||||
return self.items.copy()
|
||||
|
||||
def demonstrate_type_defaults():
|
||||
"""Demonstrate type parameter defaults"""
|
||||
print("\n2. Type Parameter Defaults:")
|
||||
print("-" * 30)
|
||||
|
||||
# Can now create containers without specifying type
|
||||
container = DataContainer()
|
||||
container.add_item("test_string")
|
||||
container.add_item(42)
|
||||
|
||||
print("✅ Generic classes with default type parameters")
|
||||
print(f" Items: {container.get_items()}")
|
||||
|
||||
# ============================================================================
|
||||
# 3. @override Decorator
|
||||
# ============================================================================
|
||||
|
||||
class BaseProcessor:
|
||||
"""Base class for demonstrating @override decorator"""
|
||||
|
||||
def process(self, data: str) -> str:
|
||||
return data.upper()
|
||||
|
||||
class AdvancedProcessor(BaseProcessor):
|
||||
"""Advanced processor using @override decorator"""
|
||||
|
||||
@override
|
||||
def process(self, data: str) -> str:
|
||||
# Enhanced processing with validation
|
||||
if not data:
|
||||
raise ValueError("Data cannot be empty")
|
||||
return data.lower().strip()
|
||||
|
||||
def demonstrate_override_decorator():
|
||||
"""Demonstrate @override decorator for method overriding"""
|
||||
print("\n3. @override Decorator:")
|
||||
print("-" * 30)
|
||||
|
||||
processor = AdvancedProcessor()
|
||||
result = processor.process(" HELLO AITBC ")
|
||||
|
||||
print("✅ Method overriding with @override decorator")
|
||||
print(f" Result: '{result}'")
|
||||
|
||||
# ============================================================================
|
||||
# 4. Performance Improvements
|
||||
# ============================================================================
|
||||
|
||||
def demonstrate_performance():
|
||||
"""Demonstrate Python 3.13 performance improvements"""
|
||||
print("\n4. Performance Improvements:")
|
||||
print("-" * 30)
|
||||
|
||||
# List comprehension performance
|
||||
start_time = time.time()
|
||||
result = [i * i for i in range(100000)]
|
||||
list_time = (time.time() - start_time) * 1000
|
||||
|
||||
# Dictionary comprehension performance
|
||||
start_time = time.time()
|
||||
result_dict = {i: i * i for i in range(100000)}
|
||||
dict_time = (time.time() - start_time) * 1000
|
||||
|
||||
print(f"✅ List comprehension (100k items): {list_time:.2f}ms")
|
||||
print(f"✅ Dict comprehension (100k items): {dict_time:.2f}ms")
|
||||
print("✅ 5-10% performance improvement over Python 3.11")
|
||||
|
||||
# ============================================================================
|
||||
# 5. Asyncio Improvements
|
||||
# ============================================================================
|
||||
|
||||
async def demonstrate_asyncio():
|
||||
"""Demonstrate asyncio performance improvements"""
|
||||
print("\n5. Asyncio Improvements:")
|
||||
print("-" * 30)
|
||||
|
||||
async def fast_task():
|
||||
await asyncio.sleep(0.001)
|
||||
return "completed"
|
||||
|
||||
# Run multiple concurrent tasks
|
||||
start_time = time.time()
|
||||
tasks = [fast_task() for _ in range(100)]
|
||||
results = await asyncio.gather(*tasks)
|
||||
async_time = (time.time() - start_time) * 1000
|
||||
|
||||
print(f"✅ 100 concurrent async tasks: {async_time:.2f}ms")
|
||||
print("✅ Enhanced asyncio performance and task scheduling")
|
||||
|
||||
# ============================================================================
|
||||
# 6. Standard Library Improvements
|
||||
# ============================================================================
|
||||
|
||||
def demonstrate_stdlib_improvements():
|
||||
"""Demonstrate standard library improvements"""
|
||||
print("\n6. Standard Library Improvements:")
|
||||
print("-" * 30)
|
||||
|
||||
# Pathlib improvements
|
||||
config_path = Path("/home/oib/windsurf/aitbc/config")
|
||||
print(f"✅ Enhanced pathlib: {config_path}")
|
||||
|
||||
# HTTP server improvements
|
||||
print("✅ Improved http.server with better error handling")
|
||||
|
||||
# JSON improvements
|
||||
import json
|
||||
data = {"status": "ok", "python": "3.13.5"}
|
||||
json_str = json.dumps(data, indent=2)
|
||||
print("✅ Enhanced JSON serialization with better formatting")
|
||||
|
||||
# ============================================================================
|
||||
# 7. Security Improvements
|
||||
# ============================================================================
|
||||
|
||||
def demonstrate_security():
|
||||
"""Demonstrate security improvements"""
|
||||
print("\n7. Security Improvements:")
|
||||
print("-" * 30)
|
||||
|
||||
# Hash randomization
|
||||
import hashlib
|
||||
data = b"aitbc_security_test"
|
||||
hash_result = hashlib.sha256(data).hexdigest()
|
||||
print(f"✅ Enhanced hash randomization: {hash_result[:16]}...")
|
||||
|
||||
# Memory safety
|
||||
try:
|
||||
# Memory-safe operations
|
||||
large_list = list(range(1000000))
|
||||
print(f"✅ Better memory safety: Created list with {len(large_list)} items")
|
||||
except MemoryError:
|
||||
print("✅ Improved memory error handling")
|
||||
|
||||
# ============================================================================
|
||||
# 8. AITBC-Specific Applications
|
||||
# ============================================================================
|
||||
|
||||
class AITBCReceiptProcessor(Generic[T]):
|
||||
"""Generic receipt processor using Python 3.13 features"""
|
||||
|
||||
def __init__(self, validator: Optional[callable] = None) -> None:
|
||||
self.validator = validator or (lambda x: True)
|
||||
self.receipts: List[T] = []
|
||||
|
||||
def add_receipt(self, receipt: T) -> bool:
|
||||
"""Add receipt with validation"""
|
||||
if self.validator(receipt):
|
||||
self.receipts.append(receipt)
|
||||
return True
|
||||
return False
|
||||
|
||||
@override
|
||||
def process_receipts(self) -> List[T]:
|
||||
"""Process all receipts with enhanced validation"""
|
||||
return [receipt for receipt in self.receipts if self.validator(receipt)]
|
||||
|
||||
def demonstrate_aitbc_applications():
|
||||
"""Demonstrate Python 3.13 features in AITBC context"""
|
||||
print("\n8. AITBC-Specific Applications:")
|
||||
print("-" * 30)
|
||||
|
||||
# Generic receipt processor
|
||||
def validate_receipt(receipt: dict) -> bool:
|
||||
return receipt.get("valid", False)
|
||||
|
||||
processor = AITBCReceiptProcessor[dict](validate_receipt)
|
||||
|
||||
# Add sample receipts
|
||||
processor.add_receipt({"id": 1, "valid": True, "amount": 100})
|
||||
processor.add_receipt({"id": 2, "valid": False, "amount": 50})
|
||||
|
||||
processed = processor.process_receipts()
|
||||
print(f"✅ Generic receipt processor: {len(processed)} valid receipts")
|
||||
|
||||
# Enhanced error handling for blockchain operations
|
||||
try:
|
||||
block_data = {"height": 1000, "hash": "0x123..."}
|
||||
next_hash = block_data["next_hash"] # This will show enhanced error
|
||||
except KeyError as e:
|
||||
print(f"✅ Enhanced blockchain error handling: {e}")
|
||||
|
||||
# ============================================================================
|
||||
# Main Execution
|
||||
# ============================================================================
|
||||
|
||||
def main():
|
||||
"""Run all demonstrations"""
|
||||
try:
|
||||
demonstrate_enhanced_errors()
|
||||
demonstrate_type_defaults()
|
||||
demonstrate_override_decorator()
|
||||
demonstrate_performance()
|
||||
|
||||
# Run async demo
|
||||
asyncio.run(demonstrate_asyncio())
|
||||
|
||||
demonstrate_stdlib_improvements()
|
||||
demonstrate_security()
|
||||
demonstrate_aitbc_applications()
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("🎉 Python 3.13.5 Features Demo Complete!")
|
||||
print("🚀 AITBC is ready to leverage these improvements!")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Demo failed: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
42
dev/examples/quick_job.py
Executable file
42
dev/examples/quick_job.py
Executable file
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Quick job submission and payment
|
||||
Usage: python3 quick_job.py "your prompt"
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
print("Usage: python3 quick_job.py \"your prompt\"")
|
||||
sys.exit(1)
|
||||
|
||||
prompt = sys.argv[1]
|
||||
|
||||
print(f"🚀 Submitting job: '{prompt}'")
|
||||
|
||||
# Submit job
|
||||
result = subprocess.run(
|
||||
f'cd ../cli && python3 client.py submit inference --prompt "{prompt}"',
|
||||
shell=True,
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
|
||||
# Extract job ID
|
||||
job_id = None
|
||||
for line in result.stdout.split('\n'):
|
||||
if "Job ID:" in line:
|
||||
job_id = line.split()[-1]
|
||||
break
|
||||
|
||||
if job_id:
|
||||
print(f"✅ Job submitted: {job_id}")
|
||||
print("\n💡 Next steps:")
|
||||
print(f" 1. Start miner: python3 cli/miner.py mine")
|
||||
print(f" 2. Check status: python3 cli/client.py status {job_id}")
|
||||
print(f" 3. After completion, pay with:")
|
||||
print(f" cd home/client && python3 wallet.py send 25.0 $(cd home/miner && python3 wallet.py address | grep Address | cut -d' ' -f4) 'Payment for {job_id}'")
|
||||
else:
|
||||
print("❌ Failed to submit job")
|
||||
104
dev/examples/simple_job_flow.py
Executable file
104
dev/examples/simple_job_flow.py
Executable file
@@ -0,0 +1,104 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Simple job flow: Client -> GPU Provider -> Payment
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import time
|
||||
|
||||
def main():
|
||||
print("📋 AITBC Job Flow: Client -> GPU Provider -> Payment")
|
||||
print("=" * 60)
|
||||
|
||||
print("\n📝 STEP 1: Client submits job 'hello'")
|
||||
print("-" * 40)
|
||||
|
||||
# Submit job
|
||||
result = subprocess.run(
|
||||
'cd ../cli && python3 client.py demo',
|
||||
shell=True,
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
print(result.stdout)
|
||||
|
||||
# Extract job ID
|
||||
job_id = None
|
||||
if "Job ID:" in result.stdout:
|
||||
for line in result.stdout.split('\n'):
|
||||
if "Job ID:" in line:
|
||||
job_id = line.split()[-1]
|
||||
break
|
||||
|
||||
if not job_id:
|
||||
print("❌ Failed to submit job")
|
||||
return
|
||||
|
||||
print(f"\n📮 Job submitted: {job_id}")
|
||||
|
||||
print("\n⛏️ STEP 2: GPU Provider processes job")
|
||||
print("-" * 40)
|
||||
print(" (Start miner with: python3 cli/miner.py mine)")
|
||||
print(" The miner will automatically pick up the job")
|
||||
|
||||
# Simulate miner processing
|
||||
print("\n 💭 Simulating job processing...")
|
||||
time.sleep(2)
|
||||
|
||||
# Miner earns AITBC
|
||||
print(" ✅ Job processed!")
|
||||
print(" 💰 Miner earned 25 AITBC")
|
||||
|
||||
# Add to miner wallet
|
||||
subprocess.run(
|
||||
f'cd miner && python3 wallet.py earn 25.0 --job {job_id} --desc "Processed hello job"',
|
||||
shell=True,
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
|
||||
print("\n💸 STEP 3: Client pays for service")
|
||||
print("-" * 40)
|
||||
|
||||
# Get miner address
|
||||
miner_result = subprocess.run(
|
||||
'cd miner && python3 wallet.py address',
|
||||
shell=True,
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
|
||||
miner_address = None
|
||||
if "Miner Address:" in miner_result.stdout:
|
||||
for line in miner_result.stdout.split('\n'):
|
||||
if "Miner Address:" in line:
|
||||
miner_address = line.split()[-1]
|
||||
break
|
||||
|
||||
if miner_address:
|
||||
# Client pays
|
||||
subprocess.run(
|
||||
f'cd client && python3 wallet.py send 25.0 {miner_address} "Payment for job {job_id}"',
|
||||
shell=True,
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
|
||||
print("\n📊 STEP 4: Final balances")
|
||||
print("-" * 40)
|
||||
|
||||
print("\n Client Wallet:")
|
||||
subprocess.run('cd client && python3 wallet.py balance', shell=True)
|
||||
|
||||
print("\n Miner Wallet:")
|
||||
subprocess.run('cd miner && python3 wallet.py balance', shell=True)
|
||||
|
||||
print("\n✅ Complete workflow demonstrated!")
|
||||
print("\n💡 To run with real GPU processing:")
|
||||
print(" 1. Start miner: python3 cli/miner.py mine")
|
||||
print(" 2. Submit job: python3 cli/client.py submit inference --prompt 'hello'")
|
||||
print(" 3. Check status: python3 cli/client.py status <job_id>")
|
||||
print(" 4. Pay manually: cd home/client && python3 wallet.py send <amount> <miner_address>")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
136
dev/examples/simulate.py
Executable file
136
dev/examples/simulate.py
Executable file
@@ -0,0 +1,136 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Complete simulation: Client pays for GPU services, Miner earns AITBC
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import subprocess
|
||||
|
||||
def run_wallet_command(wallet_type, command, description):
|
||||
"""Run a wallet command and display results"""
|
||||
print(f"\n{'='*60}")
|
||||
print(f"💼 {wallet_type}: {description}")
|
||||
print(f"{'='*60}")
|
||||
|
||||
wallet_dir = os.path.join(os.path.dirname(__file__), wallet_type.lower())
|
||||
cmd = f"cd {wallet_dir} && python3 wallet.py {command}"
|
||||
|
||||
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
|
||||
print(result.stdout)
|
||||
|
||||
if result.stderr:
|
||||
print(f"Error: {result.stderr}")
|
||||
|
||||
return result
|
||||
|
||||
def main():
|
||||
print("🎭 AITBC Local Simulation")
|
||||
print("=" * 60)
|
||||
print("Simulating client and GPU provider interactions")
|
||||
print()
|
||||
|
||||
# Step 1: Initialize wallets with genesis distribution
|
||||
print("📋 STEP 1: Initialize Wallets")
|
||||
os.system("cd /home/oib/windsurf/aitbc/home && python3 genesis.py")
|
||||
|
||||
input("\nPress Enter to continue...")
|
||||
|
||||
# Step 2: Check initial balances
|
||||
print("\n📋 STEP 2: Check Initial Balances")
|
||||
run_wallet_command("Client", "balance", "Initial client balance")
|
||||
run_wallet_command("Miner", "balance", "Initial miner balance")
|
||||
|
||||
input("\nPress Enter to continue...")
|
||||
|
||||
# Step 3: Client submits a job (using CLI tool)
|
||||
print("\n📋 STEP 3: Client Submits Job")
|
||||
print("-" * 40)
|
||||
|
||||
# Submit job to coordinator
|
||||
result = subprocess.run(
|
||||
"cd /home/oib/windsurf/aitbc/cli && python3 client.py submit inference --model llama-2-7b --prompt 'What is the future of AI?'",
|
||||
shell=True,
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
|
||||
print(result.stdout)
|
||||
|
||||
# Extract job ID if successful
|
||||
job_id = None
|
||||
if "Job ID:" in result.stdout:
|
||||
for line in result.stdout.split('\n'):
|
||||
if "Job ID:" in line:
|
||||
job_id = line.split()[-1]
|
||||
break
|
||||
|
||||
input("\nPress Enter to continue...")
|
||||
|
||||
# Step 4: Miner processes the job
|
||||
print("\n📋 STEP 4: Miner Processes Job")
|
||||
print("-" * 40)
|
||||
|
||||
if job_id:
|
||||
print(f"⛏️ Miner found job: {job_id}")
|
||||
print("⚙️ Processing job...")
|
||||
time.sleep(2)
|
||||
|
||||
# Miner earns AITBC for completing the job
|
||||
run_wallet_command(
|
||||
"Miner",
|
||||
f"earn 50.0 --job {job_id} --desc 'Inference task completed'",
|
||||
"Miner earns AITBC"
|
||||
)
|
||||
|
||||
input("\nPress Enter to continue...")
|
||||
|
||||
# Step 5: Client pays for the service
|
||||
print("\n📋 STEP 5: Client Pays for Service")
|
||||
print("-" * 40)
|
||||
|
||||
if job_id:
|
||||
# Get miner address
|
||||
miner_result = subprocess.run(
|
||||
"cd /home/oib/windsurf/aitbc/home/miner && python3 wallet.py address",
|
||||
shell=True,
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
|
||||
miner_address = None
|
||||
if "Miner Address:" in miner_result.stdout:
|
||||
for line in miner_result.stdout.split('\n'):
|
||||
if "Miner Address:" in line:
|
||||
miner_address = line.split()[-1]
|
||||
break
|
||||
|
||||
if miner_address:
|
||||
run_wallet_command(
|
||||
"Client",
|
||||
f"send 50.0 {miner_address} 'Payment for inference job {job_id}'",
|
||||
"Client pays for completed job"
|
||||
)
|
||||
|
||||
input("\nPress Enter to continue...")
|
||||
|
||||
# Step 6: Check final balances
|
||||
print("\n📋 STEP 6: Final Balances")
|
||||
run_wallet_command("Client", "balance", "Final client balance")
|
||||
run_wallet_command("Miner", "balance", "Final miner balance")
|
||||
|
||||
print("\n🎉 Simulation Complete!")
|
||||
print("=" * 60)
|
||||
print("Summary:")
|
||||
print(" • Client submitted job and paid 50 AITBC")
|
||||
print(" • Miner processed job and earned 50 AITBC")
|
||||
print(" • Transaction recorded on blockchain")
|
||||
print()
|
||||
print("💡 You can:")
|
||||
print(" • Run 'cd home/client && python3 wallet.py history' to see client transactions")
|
||||
print(" • Run 'cd home/miner && python3 wallet.py stats' to see miner earnings")
|
||||
print(" • Submit more jobs with the CLI tools")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
158
dev/examples/wallet.py
Executable file
158
dev/examples/wallet.py
Executable file
@@ -0,0 +1,158 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
AITBC Wallet CLI Tool - Track earnings and manage wallet
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
from datetime import datetime
|
||||
from typing import Dict, List
|
||||
|
||||
class AITBCWallet:
|
||||
def __init__(self, wallet_file: str = None):
|
||||
if wallet_file is None:
|
||||
wallet_file = os.path.expanduser("~/.aitbc_wallet.json")
|
||||
|
||||
self.wallet_file = wallet_file
|
||||
self.data = self._load_wallet()
|
||||
|
||||
def _load_wallet(self) -> dict:
|
||||
"""Load wallet data from file"""
|
||||
if os.path.exists(self.wallet_file):
|
||||
try:
|
||||
with open(self.wallet_file, 'r') as f:
|
||||
return json.load(f)
|
||||
except:
|
||||
pass
|
||||
|
||||
# Create new wallet
|
||||
return {
|
||||
"address": "aitbc1" + os.urandom(10).hex(),
|
||||
"balance": 0.0,
|
||||
"transactions": [],
|
||||
"created_at": datetime.now().isoformat()
|
||||
}
|
||||
|
||||
def save(self):
|
||||
"""Save wallet to file"""
|
||||
with open(self.wallet_file, 'w') as f:
|
||||
json.dump(self.data, f, indent=2)
|
||||
|
||||
def add_earnings(self, amount: float, job_id: str, description: str = ""):
|
||||
"""Add earnings from completed job"""
|
||||
transaction = {
|
||||
"type": "earn",
|
||||
"amount": amount,
|
||||
"job_id": job_id,
|
||||
"description": description or f"Job {job_id}",
|
||||
"timestamp": datetime.now().isoformat()
|
||||
}
|
||||
|
||||
self.data["transactions"].append(transaction)
|
||||
self.data["balance"] += amount
|
||||
self.save()
|
||||
|
||||
print(f"💰 Added {amount} AITBC to wallet")
|
||||
print(f" New balance: {self.data['balance']} AITBC")
|
||||
|
||||
def spend(self, amount: float, description: str):
|
||||
"""Spend AITBC"""
|
||||
if self.data["balance"] < amount:
|
||||
print(f"❌ Insufficient balance!")
|
||||
print(f" Balance: {self.data['balance']} AITBC")
|
||||
print(f" Needed: {amount} AITBC")
|
||||
return False
|
||||
|
||||
transaction = {
|
||||
"type": "spend",
|
||||
"amount": -amount,
|
||||
"description": description,
|
||||
"timestamp": datetime.now().isoformat()
|
||||
}
|
||||
|
||||
self.data["transactions"].append(transaction)
|
||||
self.data["balance"] -= amount
|
||||
self.save()
|
||||
|
||||
print(f"💸 Spent {amount} AITBC")
|
||||
print(f" Remaining: {self.data['balance']} AITBC")
|
||||
return True
|
||||
|
||||
def show_balance(self):
|
||||
"""Show wallet balance"""
|
||||
print(f"💳 Wallet Address: {self.data['address']}")
|
||||
print(f"💰 Balance: {self.data['balance']} AITBC")
|
||||
print(f"📊 Total Transactions: {len(self.data['transactions'])}")
|
||||
|
||||
def show_history(self, limit: int = 10):
|
||||
"""Show transaction history"""
|
||||
transactions = self.data["transactions"][-limit:]
|
||||
|
||||
if not transactions:
|
||||
print("📭 No transactions yet")
|
||||
return
|
||||
|
||||
print(f"📜 Recent Transactions (last {limit}):")
|
||||
print("-" * 60)
|
||||
|
||||
for tx in reversed(transactions):
|
||||
symbol = "💰" if tx["type"] == "earn" else "💸"
|
||||
print(f"{symbol} {tx['amount']:+8.2f} AITBC | {tx.get('description', 'N/A')}")
|
||||
print(f" 📅 {tx['timestamp']}")
|
||||
if "job_id" in tx:
|
||||
print(f" 🆔 Job: {tx['job_id']}")
|
||||
print()
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="AITBC Wallet CLI")
|
||||
parser.add_argument("--wallet", help="Wallet file path")
|
||||
|
||||
subparsers = parser.add_subparsers(dest="command", help="Commands")
|
||||
|
||||
# Balance command
|
||||
balance_parser = subparsers.add_parser("balance", help="Show balance")
|
||||
|
||||
# History command
|
||||
history_parser = subparsers.add_parser("history", help="Show transaction history")
|
||||
history_parser.add_argument("--limit", type=int, default=10, help="Number of transactions")
|
||||
|
||||
# Earn command
|
||||
earn_parser = subparsers.add_parser("earn", help="Add earnings")
|
||||
earn_parser.add_argument("amount", type=float, help="Amount earned")
|
||||
earn_parser.add_argument("--job", help="Job ID")
|
||||
earn_parser.add_argument("--desc", help="Description")
|
||||
|
||||
# Spend command
|
||||
spend_parser = subparsers.add_parser("spend", help="Spend AITBC")
|
||||
spend_parser.add_argument("amount", type=float, help="Amount to spend")
|
||||
spend_parser.add_argument("description", help="What you're spending on")
|
||||
|
||||
# Address command
|
||||
address_parser = subparsers.add_parser("address", help="Show wallet address")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if not args.command:
|
||||
parser.print_help()
|
||||
return
|
||||
|
||||
wallet = AITBCWallet(args.wallet)
|
||||
|
||||
if args.command == "balance":
|
||||
wallet.show_balance()
|
||||
|
||||
elif args.command == "history":
|
||||
wallet.show_history(args.limit)
|
||||
|
||||
elif args.command == "earn":
|
||||
wallet.add_earnings(args.amount, args.job or "unknown", args.desc or "")
|
||||
|
||||
elif args.command == "spend":
|
||||
wallet.spend(args.amount, args.description)
|
||||
|
||||
elif args.command == "address":
|
||||
print(f"💳 Wallet Address: {wallet.data['address']}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user