-
Notifications
You must be signed in to change notification settings - Fork 9
/
connect.py
64 lines (54 loc) · 2.24 KB
/
connect.py
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
from binascii import unhexlify, hexlify
from io import BytesIO
import asyncio
from network import NetworkEnvelope, NETWORK_MAGIC
from helper import (
double_sha256,
int_to_little_endian,
little_endian_to_int,
)
VERSION = unhexlify('f9beb4d976657273696f6e0000000000650000005f1a69d2721101000100000000000000bc8f5e5400000000010000000000000000000000000000000000ffffc61b6409208d010000000000000000000000000000000000ffffcb0071c0208d128035cbc97953f80f2f5361746f7368693a302e392e332fcf05050001')
VERACK = unhexlify('f9beb4d976657261636b000000000000000000005df6e0e2')
class NodeConnection:
def __init__(self, host, port):
self.host = host
self.port = port
self.reader = None
self.writer = None
self.q = asyncio.Queue()
async def connect(self, loop):
self.reader, self.writer = await asyncio.open_connection(
host=self.host, port=self.port)
print('connected')
self.send(VERSION)
print('sent version')
await asyncio.wait([self.receive(), self.process_queue()])
def send(self, msg):
self.writer.write(msg)
async def receive(self):
print("start receiving")
while True:
magic = await self.reader.read(4)
if magic != NETWORK_MAGIC:
raise RuntimeError('Network Magic not at beginning of stream')
command = await self.reader.read(12)
payload_length = little_endian_to_int(await self.reader.read(4))
checksum = await self.reader.read(4)
payload = await self.reader.read(payload_length)
# check the checksum
if double_sha256(payload)[:4] != checksum:
raise RuntimeError('Payload and Checksum do not match')
await self.q.put(NetworkEnvelope(command, payload))
async def process_queue(self):
print("start processing")
while True:
envelope = await self.q.get()
if envelope.command.startswith(b'version'):
print('sending verack')
self.send(VERACK)
else:
print(envelope)
loop = asyncio.get_event_loop()
node = NodeConnection(host='35.187.200.6', port=8333)
task = loop.run_until_complete(node.connect(loop))
loop.close()