Skip to content

Commit

Permalink
Update mp2_service for CP2
Browse files Browse the repository at this point in the history
  • Loading branch information
chenghu3 committed Mar 29, 2019
1 parent 7c104aa commit d10a432
Showing 1 changed file with 62 additions and 18 deletions.
80 changes: 62 additions & 18 deletions mp2_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,33 @@
import random
import re
import time
from collections import defaultdict

if len(sys.argv) != 3:
print("Usage: mp2_service.py <port_number> <tx_rate>")
if len(sys.argv) < 3 or len(sys.argv) > 4:
print("Usage: mp2_service.py <port_number> <tx_rate> [block_rate]")
sys.exit(1)

port = int(sys.argv[1])
tx_rate = float(sys.argv[2])
if len(sys.argv) > 3:
block_rate = float(sys.argv[3])
else:
block_rate = 1.0/60

connections = []
kill_connections = []
snap_event = asyncio.Event()

oracle = {}
balances = defaultdict(int)
balances[0] = 1000

async def handle_connection(reader, writer):
global balances
addr = writer.get_extra_info('peername')
print(f"Received connection from {addr}")

solving = None

connect_line = await reader.readline()
m = re.match(r'CONNECT\s+(.*)$', connect_line.decode(), re.I)
if not m:
Expand All @@ -41,25 +51,57 @@ async def handle_connection(reader, writer):
event_task = asyncio.ensure_future(snap_event.wait())

while True:

timeout = random.expovariate(tx_rate / len(connections))
tx_timeout = random.expovariate(tx_rate / len(connections))
if solving:
block_timeout = random.expovariate(block_rate / len(connections))
timeout = min(tx_timeout, block_timeout)
else:
timeout = tx_timeout
ready, pending = await asyncio.wait([command_task, event_task], timeout=timeout,
return_when=asyncio.FIRST_COMPLETED)
if not ready: # timeout, send transaction
tx_time = time.time()
tx_id = format(random.randrange(2 ** 128), "032x")
tx_from = random.randrange(2 ** 20)
tx_to = random.randrange(2 ** 20)
tx_amount = random.randrange(2 ** 10)
tx = f"{tx_time:#.6f} {tx_id} {tx_from} {tx_to} {tx_amount}"
print(f"Sending transaction {tx} to {addr}")
writer.write(f"TRANSACTION {tx}\n".encode())
await writer.drain()
if not ready: # timeout
if solving and block_timeout < tx_timeout: # block solution
solution = format(random.randrange(2**256), "032x")
oracle[solving] = solution
print(f"Sending solution {solving} {solution} to {addr}")
writer.write(f"SOLVED {solving} {solution}\n".encode())
await writer.drain()
solving = None
else:
tx_time = time.time()
tx_id = format(random.randrange(2 ** 128), "032x")
tx_from = random.choice([ k for k,v in balances.items() if v != 0])
if len(balances) > 1:
tx_to = random.choice([ k for k in balances.keys() if k != tx_from])
if tx_to == 0:
tx_to = len(balances)
else:
tx_to = 1
tx_amount = random.randrange(1, balances[tx_from]+1)
if tx_from != 0:
balances[tx_from] -= tx_amount
balances[tx_to] += tx_amount
tx = f"{tx_time:#.6f} {tx_id} {tx_from} {tx_to} {tx_amount}"
print(f"Sending transaction {tx} to {addr}")
print(f"New balances: {tx_from}: {balances[tx_from]}, {tx_to}: {balances[tx_to]}")
writer.write(f"TRANSACTION {tx}\n".encode())
await writer.drain()
else:
if command_task in ready:
command = command_task.result()
if True:
print(f"Unexpected command `{command.decode().strip()}' from {addr}, disconnecting")
command, *args = command_task.result().decode().strip().split()
if command.lower() == "solve" and len(args) == 1:
solving = args[0]
print(f"Solving {solving} for {addr}")
elif command.lower() == "verify" and len(args) == 2:
if oracle.get(args[0]) == args[1]:
print(f"Verification succeeded {args[0]} -> {args[1]} {addr}")
writer.write(f"VERIFY OK {args[0]} {args[1]}\n".encode())
else:
print(f"Verification failed {args[0]} -> {args[1]} {addr}")
writer.write(f"VERIFY FAIL {args[0]} {args[1]}\n".encode())
await writer.drain()
else:
print(f"Unexpected command `{command} {' '.join(args)}' from {addr}, disconnecting")
break
# left here to remember when we start supporting commands
command_task = asyncio.ensure_future(reader.readline())
Expand Down Expand Up @@ -93,6 +135,8 @@ def handle_command():
print(f"Unknown command: `{command.strip()}''")




loop = asyncio.get_event_loop()
coro = asyncio.start_server(handle_connection, None, port, loop=loop)
server = loop.run_until_complete(coro)
Expand Down

0 comments on commit d10a432

Please sign in to comment.