| 40 | return '%i:%s' % (self.code,self.reason or '*') |
| 41 | |
| 42 | class TestNode(NodeConnCB): |
| 43 | |
| 44 | def __init__(self, block_store, tx_store): |
| 45 | super().__init__() |
| 46 | self.conn = None |
| 47 | self.bestblockhash = None |
| 48 | self.block_store = block_store |
| 49 | self.block_request_map = {} |
| 50 | self.tx_store = tx_store |
| 51 | self.tx_request_map = {} |
| 52 | self.block_reject_map = {} |
| 53 | self.tx_reject_map = {} |
| 54 | |
| 55 | # When the pingmap is non-empty we're waiting for |
| 56 | # a response |
| 57 | self.pingMap = {} |
| 58 | self.lastInv = [] |
| 59 | self.closed = False |
| 60 | |
| 61 | def on_close(self, conn): |
| 62 | self.closed = True |
| 63 | |
| 64 | def add_connection(self, conn): |
| 65 | self.conn = conn |
| 66 | |
| 67 | def on_headers(self, conn, message): |
| 68 | if len(message.headers) > 0: |
| 69 | best_header = message.headers[-1] |
| 70 | best_header.calc_sha256() |
| 71 | self.bestblockhash = best_header.sha256 |
| 72 | |
| 73 | def on_getheaders(self, conn, message): |
| 74 | response = self.block_store.headers_for(message.locator, message.hashstop) |
| 75 | if response is not None: |
| 76 | conn.send_message(response) |
| 77 | |
| 78 | def on_getdata(self, conn, message): |
| 79 | [conn.send_message(r) for r in self.block_store.get_blocks(message.inv)] |
| 80 | [conn.send_message(r) for r in self.tx_store.get_transactions(message.inv)] |
| 81 | |
| 82 | for i in message.inv: |
| 83 | if i.type == 1: |
| 84 | self.tx_request_map[i.hash] = True |
| 85 | elif i.type == 2: |
| 86 | self.block_request_map[i.hash] = True |
| 87 | |
| 88 | def on_inv(self, conn, message): |
| 89 | self.lastInv = [x.hash for x in message.inv] |
| 90 | |
| 91 | def on_pong(self, conn, message): |
| 92 | try: |
| 93 | del self.pingMap[message.nonce] |
| 94 | except KeyError: |
| 95 | raise AssertionError("Got pong for unknown ping [%s]" % repr(message)) |
| 96 | |
| 97 | def on_reject(self, conn, message): |
| 98 | if message.message == b'tx': |
| 99 | self.tx_reject_map[message.data] = RejectResult(message.code, message.reason) |
no outgoing calls