| | |
| | """ |
| | MEP Race Test FIXED: Ensure task is broadcast AFTER all providers connect. |
| | """ |
| | import asyncio |
| | import websockets |
| | import json |
| | import requests |
| | import uuid |
| | import time |
| | import urllib.parse |
| | from identity import MEPIdentity |
| |
|
| | HUB_URL = "http://localhost:8000" |
| | WS_URL = "ws://localhost:8000" |
| |
|
| | class RacingProvider: |
| | def __init__(self, name, location): |
| | self.name = name |
| | self.location = location |
| | self.identity = MEPIdentity(f"{name.replace(' ', '_')}_{uuid.uuid4().hex[:6]}.pem") |
| | self.node_id = self.identity.node_id |
| | self.balance = 0 |
| | self.won_race = False |
| | self.response_time = None |
| | self.ws = None |
| | |
| | async def connect(self): |
| | """Connect to hub and wait for tasks.""" |
| | requests.post(f"{HUB_URL}/register", json={"pubkey": self.identity.pub_pem}) |
| | ts = str(int(time.time())) |
| | sig = self.identity.sign(self.node_id, ts) |
| | sig_safe = urllib.parse.quote(sig) |
| | self.ws = await websockets.connect(f"{WS_URL}/ws/{self.node_id}?timestamp={ts}&signature={sig_safe}") |
| | print(f"[{self.name}] Connected to hub") |
| | return self.ws |
| | |
| | async def listen_for_task(self, task_id, bounty): |
| | """Listen for specific task and try to win.""" |
| | try: |
| | start_time = time.time() |
| | msg = await asyncio.wait_for(self.ws.recv(), timeout=2.0) |
| | data = json.loads(msg) |
| | |
| | if data["event"] == "new_task" and data["data"]["id"] == task_id: |
| | self.response_time = time.time() - start_time |
| | print(f"[{self.name}] π GOT TASK! Response: {self.response_time:.3f}s") |
| | |
| | |
| | await asyncio.sleep(0.05) |
| | |
| | result = f"WON by {self.name} from {self.location}. Response time: {self.response_time:.3f}s" |
| | payload_str = json.dumps({ |
| | "task_id": task_id, |
| | "provider_id": self.node_id, |
| | "result_payload": result |
| | }) |
| | headers = self.identity.get_auth_headers(payload_str) |
| | headers["Content-Type"] = "application/json" |
| | resp = requests.post(f"{HUB_URL}/tasks/complete", data=payload_str, headers=headers) |
| | |
| | if resp.status_code == 200: |
| | self.won_race = True |
| | self.balance = resp.json()["new_balance"] |
| | return True |
| | |
| | except asyncio.TimeoutError: |
| | pass |
| | except Exception as e: |
| | print(f"[{self.name}] Error: {e}") |
| | |
| | return False |
| | |
| | async def close(self): |
| | if self.ws: |
| | await self.ws.close() |
| |
|
| | async def run_race(): |
| | print("=" * 60) |
| | print("MEP GLOBAL RACE TEST: Real Competition") |
| | print("=" * 60) |
| | |
| | |
| | providers = [ |
| | RacingProvider("FastProvider-USA", "New York"), |
| | RacingProvider("SlowProvider-EU", "Berlin"), |
| | RacingProvider("QuickProvider-Asia", "Singapore"), |
| | RacingProvider("SteadyProvider-AU", "Sydney") |
| | ] |
| | |
| | |
| | print("\nπ Connecting providers to hub...") |
| | for provider in providers: |
| | await provider.connect() |
| | |
| | await asyncio.sleep(0.5) |
| | |
| | |
| | consumer = MEPIdentity(f"race_consumer_{uuid.uuid4().hex[:6]}.pem") |
| | requests.post(f"{HUB_URL}/register", json={"pubkey": consumer.pub_pem}) |
| | |
| | task_payload = "Which provider is fastest in the MEP race?" |
| | bounty = 7.5 |
| | |
| | print(f"\nπ€ Broadcasting task to {len(providers)} connected providers...") |
| | print(f" Task: {task_payload}") |
| | print(f" Bounty: {bounty} SECONDS") |
| | |
| | payload_str = json.dumps({ |
| | "consumer_id": consumer.node_id, |
| | "payload": task_payload, |
| | "bounty": bounty |
| | }) |
| | headers = consumer.get_auth_headers(payload_str) |
| | headers["Content-Type"] = "application/json" |
| | resp = requests.post(f"{HUB_URL}/tasks/submit", data=payload_str, headers=headers) |
| | |
| | task_id = resp.json()["task_id"] |
| | print(f" Task ID: {task_id[:8]}...") |
| | |
| | |
| | print("\nπ ALL PROVIDERS LISTENING... RACE STARTS!") |
| | await asyncio.gather(*[provider.listen_for_task(task_id, bounty) for provider in providers]) |
| | |
| | |
| | for provider in providers: |
| | await provider.close() |
| | |
| | |
| | print("\n" + "=" * 60) |
| | print("RACE RESULTS:") |
| | print("=" * 60) |
| | |
| | winners = [m for m in providers if m.won_race] |
| | |
| | if winners: |
| | winner = winners[0] |
| | print(f"π WINNER: {winner.name} from {winner.location}") |
| | print(f" Response time: {winner.response_time:.3f} seconds") |
| | print(f" Earned: {bounty} SECONDS") |
| | print(f" New balance: {winner.balance} SECONDS") |
| | |
| | |
| | print("\nπ All response times:") |
| | for provider in providers: |
| | if provider.response_time: |
| | status = "β
WON" if provider.won_race else "β Lost" |
| | print(f" {status} {provider.name:20} {provider.response_time:.3f}s") |
| | else: |
| | print("β No winner - check hub logs") |
| | |
| | |
| | balance_resp = requests.get(f"{HUB_URL}/balance/{consumer.node_id}") |
| | consumer_balance = balance_resp.json()["balance_seconds"] |
| | print(f"\nπ° Consumer balance: {consumer_balance} SECONDS") |
| | |
| | print("\nβ
This proves MEP creates a competitive efficiency market.") |
| | print(" Fastest node wins the SECONDS. Slow nodes get nothing.") |
| |
|
| | if __name__ == "__main__": |
| | asyncio.run(run_race()) |
| |
|