File size: 6,045 Bytes
84506ca
 
 
 
 
 
 
 
 
 
 
a25490a
 
84506ca
 
 
 
c412eea
84506ca
 
 
a25490a
 
84506ca
 
 
 
 
 
 
 
 
a25490a
84506ca
 
 
a25490a
 
 
 
84506ca
 
 
 
 
 
 
 
 
 
 
c412eea
84506ca
 
 
 
 
a25490a
84506ca
 
 
 
a25490a
 
 
84506ca
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a25490a
 
84506ca
c412eea
 
 
 
 
 
84506ca
 
 
 
 
 
 
 
 
a25490a
 
84506ca
 
 
a25490a
 
 
84506ca
 
 
 
 
c412eea
 
 
84506ca
 
 
 
 
 
 
 
c412eea
 
 
 
84506ca
c412eea
 
84506ca
 
 
 
 
 
 
 
 
a25490a
84506ca
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#!/usr/bin/env python3
"""
MEP Race Test: Multiple providers compete for the same task.
Simulates a global network of sleeping nodes.
"""
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
        
    async def compete(self, task_id, task_payload, bounty):
        """Connect and try to win the task."""
        print(f"[{self.name} in {self.location}] Connecting to MEP Hub...")
        
        # Register
        requests.post(f"{HUB_URL}/register", json={"pubkey": self.identity.pub_pem})
        
        # Connect via WebSocket
        start_time = time.time()
        ts = str(int(time.time()))
        sig = self.identity.sign(self.node_id, ts)
        sig_safe = urllib.parse.quote(sig)
        async with websockets.connect(f"{WS_URL}/ws/{self.node_id}?timestamp={ts}&signature={sig_safe}") as ws:
            print(f"[{self.name}] Connected. Waiting for task {task_id[:8]}...")
            
            try:
                # Listen for the task
                msg = await asyncio.wait_for(ws.recv(), timeout=5.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 THE TASK! Response: {self.response_time:.3f}s")
                    
                    # Simulate processing (faster providers win)
                    process_time = 0.1 if "fast" in self.name.lower() else 0.5
                    await asyncio.sleep(process_time)
                    
                    # Submit result
                    result = f"Processed by {self.name} from {self.location}. Task: {task_payload[:30]}..."
                    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"]
                        print(f"[{self.name}] ๐ŸŽ‰ WON THE RACE! Earned {bounty} SECONDS")
                    else:
                        print(f"[{self.name}] โŒ Race lost (someone else finished first)")
                        
            except asyncio.TimeoutError:
                print(f"[{self.name}] Timeout - task already taken")
            except Exception as e:
                print(f"[{self.name}] Error: {e}")

async def run_race():
    print("=" * 60)
    print("MEP GLOBAL RACE TEST: Multiple Nodes Compete for One Task")
    print("=" * 60)
    
    # Register consumer
    consumer = MEPIdentity(f"race_consumer_{uuid.uuid4().hex[:6]}.pem")
    requests.post(f"{HUB_URL}/register", json={"pubkey": consumer.pub_pem})
    
    # Create 4 providers in different "locations"
    providers = [
        RacingProvider("FastProvider-USA", "New York"),
        RacingProvider("SlowProvider-EU", "Berlin"),
        RacingProvider("QuickProvider-Asia", "Singapore"),
        RacingProvider("SteadyProvider-AU", "Sydney")
    ]
    
    # Submit a task
    task_payload = "Analyze the MEP race dynamics and provide insights"
    bounty = 8.5
    
    print(f"\n๐Ÿ“ค Submitting task: {task_payload[:50]}...")
    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_data = resp.json()
    task_id = task_data["task_id"]
    print(f"   Task ID: {task_id[:8]}...")
    
    # Start all providers simultaneously
    print("\n๐Ÿ Starting providers...")
    tasks = [provider.compete(task_id, task_payload, bounty) for provider in providers]
    await asyncio.gather(*tasks)
    
    # Results
    print("\n" + "=" * 60)
    print("RACE RESULTS:")
    print("=" * 60)
    
    winner = None
    for provider in providers:
        status = "๐Ÿ† WINNER" if provider.won_race else "โŒ Lost"
        time_str = f"{provider.response_time:.3f}s" if provider.response_time else "N/A"
        print(f"{status} {provider.name:20} {provider.location:15} Response: {time_str:8} Balance: {provider.balance}")
        
        if provider.won_race:
            winner = provider
    
    if winner:
        print(f"\n๐ŸŽฏ The market chose: {winner.name} from {winner.location}")
        print(f"   Reason: Fastest response time ({winner.response_time:.3f}s)")
        print(f"   Economics: Earned {bounty} SECONDS for being efficient")
    else:
        print("\nโš ๏ธ No winner - task may have failed")
    
    # Check consumer balance
    balance_resp = requests.get(f"{HUB_URL}/balance/{consumer.node_id}")
    consumer_balance = balance_resp.json()["balance_seconds"]
    print(f"\n๐Ÿ’ฐ Consumer spent {bounty} SECONDS, new balance: {consumer_balance}")
    
    print("\nโœ… Race test complete. This simulates how MEP creates a")
    print("   global efficiency market: fastest nodes win SECONDS.")

if __name__ == "__main__":
    asyncio.run(run_race())