async def test_bounds(self): headers = MainHeaders(':memory:') await headers.connect(0, self.get_bytes(block_bytes(3001))) self.assertEqual(headers.height, 3000) with self.assertRaises(IndexError): _ = headers[3001] with self.assertRaises(IndexError): _ = headers[-1] self.assertIsNotNone(headers[3000]) self.assertIsNotNone(headers[0])
async def test_repair(self): headers = MainHeaders(':memory:') await headers.connect(0, self.get_bytes(block_bytes(3001))) self.assertEqual(headers.height, 3000) await headers.repair() self.assertEqual(headers.height, 3000) # corrupt the middle of it headers.io.seek(block_bytes(1500)) headers.io.write(b"wtf") await headers.repair() self.assertEqual(headers.height, 1499) self.assertEqual(len(headers), 1500) # corrupt by appending headers.io.seek(block_bytes(len(headers))) headers.io.write(b"appending") headers._size = None await headers.repair() self.assertEqual(headers.height, 1499) await headers.connect(len(headers), self.get_bytes(block_bytes(3001 - 1500), after=block_bytes(1500))) self.assertEqual(headers.height, 3000)
async def test_checkpointed_writer(self): headers = MainHeaders(':memory:') headers.checkpoint = 100, hexlify( sha256(self.get_bytes(block_bytes(100)))) genblocks = lambda start, end: self.get_bytes(block_bytes(end - start), block_bytes(start)) async with headers.checkpointed_connector() as buff: buff.write(genblocks(0, 10)) self.assertEqual(len(headers), 10) async with headers.checkpointed_connector() as buff: buff.write(genblocks(10, 100)) self.assertEqual(len(headers), 100) headers = MainHeaders(':memory:') async with headers.checkpointed_connector() as buff: buff.write(genblocks(0, 300)) self.assertEqual(len(headers), 300)
async def test_concurrency(self): BLOCKS = 30 headers_temporary_file = tempfile.mktemp() headers = MainHeaders(headers_temporary_file) await headers.open() self.addCleanup(os.remove, headers_temporary_file) async def writer(): for block_index in range(BLOCKS): await headers.connect(block_index, self.get_bytes(block_bytes(block_index + 1), block_bytes(block_index))) async def reader(): for block_index in range(BLOCKS): while len(headers) < block_index: await asyncio.sleep(0.000001) assert headers[block_index]['block_height'] == block_index reader_task = asyncio.create_task(reader()) await writer() await reader_task
async def test_connect_from_genesis_to_3000_past_first_chunk_at_2016(self): headers = MainHeaders(':memory:') self.assertEqual(headers.height, -1) await headers.connect(0, self.get_bytes(block_bytes(3001))) self.assertEqual(headers.height, 3000)
async def get_headers(self, upto: int = -1): h = MainHeaders(':memory:') h.io.write(self.get_bytes(upto)) return h