mirror of
https://github.com/LBRYFoundation/LBRY-Vault.git
synced 2025-09-02 10:15:20 +00:00
interface: block header search simplifications
This commit is contained in:
parent
ab94a47b8e
commit
da23e71db1
2 changed files with 23 additions and 27 deletions
|
@ -314,6 +314,7 @@ class Interface(PrintError):
|
|||
|
||||
async def get_block_header(self, height, assert_mode):
|
||||
# use lower timeout as we usually have network.bhi_lock here
|
||||
self.print_error('requesting block header {} in mode {}'.format(height, assert_mode))
|
||||
timeout = 5 if not self.proxy else 10
|
||||
res = await self.session.send_request('blockchain.block.header', [height], timeout=timeout)
|
||||
return blockchain.deserialize_header(bytes.fromhex(res), height)
|
||||
|
@ -385,20 +386,20 @@ class Interface(PrintError):
|
|||
raise GracefulDisconnect('server tip below max checkpoint')
|
||||
self.mark_ready()
|
||||
async with self.network.bhi_lock:
|
||||
if self.blockchain.height() < height - 1:
|
||||
_, height = await self.sync_until(height, None)
|
||||
if self.blockchain.height() >= height and self.blockchain.check_header(header):
|
||||
# another interface amended the blockchain
|
||||
self.print_error("skipping header", height)
|
||||
continue
|
||||
height = min(height, self.tip)
|
||||
_, height = await self.step(height, header)
|
||||
# in the simple case, height == self.tip+1
|
||||
if height <= self.tip:
|
||||
await self.sync_until(height)
|
||||
|
||||
async def sync_until(self, height, next_height=None):
|
||||
if next_height is None:
|
||||
next_height = self.tip
|
||||
last = None
|
||||
while last is None or height < next_height:
|
||||
while last is None or height <= next_height:
|
||||
if next_height > height + 10:
|
||||
could_connect, num_headers = await self.request_chunk(height, next_height)
|
||||
if not could_connect:
|
||||
|
@ -463,7 +464,9 @@ class Interface(PrintError):
|
|||
if not real and not mock:
|
||||
raise Exception('unexpected bad header during binary' + str(bad_header)) # line 948 in 8e69174374aee87d73cd2f8005fbbe87c93eee9c's network.py
|
||||
branch = blockchain.blockchains.get(bad)
|
||||
self.print_error("binary search exited. good {}, bad {}".format(good, bad))
|
||||
if branch is not None:
|
||||
self.print_error("existing fork found at bad height {}".format(bad))
|
||||
ismocking = type(branch) is dict
|
||||
# FIXME: it does not seem sufficient to check that the branch
|
||||
# contains the bad_header. what if self.blockchain doesn't?
|
||||
|
@ -477,24 +480,18 @@ class Interface(PrintError):
|
|||
height += 1
|
||||
return 'join', height
|
||||
else:
|
||||
if not ismocking and branch.parent().check_header(header) \
|
||||
or ismocking and branch['parent']['check'](header):
|
||||
self.print_error('reorg', bad, self.tip)
|
||||
self.blockchain = branch.parent() if not ismocking else branch['parent']
|
||||
height = bad
|
||||
header = await self.get_block_header(height, 'binary')
|
||||
else:
|
||||
height = bad + 1
|
||||
if ismocking:
|
||||
self.print_error("TODO replace blockchain")
|
||||
return 'conflict', height
|
||||
self.print_error('forkpoint conflicts with existing fork', branch.path())
|
||||
branch.write(b'', 0)
|
||||
branch.save_header(bad_header)
|
||||
self.blockchain = branch
|
||||
height = bad + 1
|
||||
if ismocking:
|
||||
self.print_error("TODO replace blockchain")
|
||||
return 'conflict', height
|
||||
self.print_error('forkpoint conflicts with existing fork', branch.path())
|
||||
branch.write(b'', 0)
|
||||
branch.save_header(bad_header)
|
||||
self.blockchain = branch
|
||||
return 'conflict', height
|
||||
else:
|
||||
bh = self.blockchain.height()
|
||||
self.print_error("no existing fork yet at bad height {}. local chain height: {}".format(bad, bh))
|
||||
if bh > good:
|
||||
forkfun = self.blockchain.fork
|
||||
if 'mock' in bad_header:
|
||||
|
|
|
@ -49,7 +49,7 @@ class TestNetwork(unittest.TestCase):
|
|||
self.interface.q.put_nowait({'block_height': 5, 'mock': {'binary':1,'check':lambda x: True, 'connect': lambda x: True}})
|
||||
self.interface.q.put_nowait({'block_height': 6, 'mock': {'binary':1,'check':lambda x: True, 'connect': lambda x: True}})
|
||||
ifa = self.interface
|
||||
self.assertEqual(('fork', 8), asyncio.get_event_loop().run_until_complete(ifa.sync_until(8, next_height=8)))
|
||||
self.assertEqual(('fork', 8), asyncio.get_event_loop().run_until_complete(ifa.sync_until(8, next_height=7)))
|
||||
self.assertEqual(self.interface.q.qsize(), 0)
|
||||
|
||||
def test_new_can_connect_during_backward(self):
|
||||
|
@ -62,7 +62,7 @@ class TestNetwork(unittest.TestCase):
|
|||
self.interface.q.put_nowait({'block_height': 3, 'mock': {'catchup':1, 'check': lambda x: False, 'connect': lambda x: True}})
|
||||
self.interface.q.put_nowait({'block_height': 4, 'mock': {'catchup':1, 'check': lambda x: False, 'connect': lambda x: True}})
|
||||
ifa = self.interface
|
||||
self.assertEqual(('catchup', 5), asyncio.get_event_loop().run_until_complete(ifa.sync_until(8, next_height=5)))
|
||||
self.assertEqual(('catchup', 5), asyncio.get_event_loop().run_until_complete(ifa.sync_until(8, next_height=4)))
|
||||
self.assertEqual(self.interface.q.qsize(), 0)
|
||||
|
||||
def mock_fork(self, bad_header):
|
||||
|
@ -79,7 +79,7 @@ class TestNetwork(unittest.TestCase):
|
|||
self.interface.q.put_nowait({'block_height': 5, 'mock': {'catchup':1, 'check': lambda x: False, 'connect': lambda x: True}})
|
||||
self.interface.q.put_nowait({'block_height': 6, 'mock': {'catchup':1, 'check': lambda x: False, 'connect': lambda x: True}})
|
||||
ifa = self.interface
|
||||
self.assertEqual(('catchup', 7), asyncio.get_event_loop().run_until_complete(ifa.sync_until(8, next_height=7)))
|
||||
self.assertEqual(('catchup', 7), asyncio.get_event_loop().run_until_complete(ifa.sync_until(8, next_height=6)))
|
||||
self.assertEqual(self.interface.q.qsize(), 0)
|
||||
|
||||
def test_new_join(self):
|
||||
|
@ -91,7 +91,7 @@ class TestNetwork(unittest.TestCase):
|
|||
self.interface.q.put_nowait({'block_height': 5, 'mock': {'binary':1, 'check': lambda x: True, 'connect': lambda x: False}})
|
||||
self.interface.q.put_nowait({'block_height': 6, 'mock': {'binary':1, 'check': lambda x: True, 'connect': lambda x: True}})
|
||||
ifa = self.interface
|
||||
self.assertEqual(('join', 7), asyncio.get_event_loop().run_until_complete(ifa.sync_until(8, next_height=7)))
|
||||
self.assertEqual(('join', 7), asyncio.get_event_loop().run_until_complete(ifa.sync_until(8, next_height=6)))
|
||||
self.assertEqual(self.interface.q.qsize(), 0)
|
||||
|
||||
def test_new_reorg(self):
|
||||
|
@ -100,7 +100,7 @@ class TestNetwork(unittest.TestCase):
|
|||
nonlocal times
|
||||
self.assertEqual(header['block_height'], 7)
|
||||
times += 1
|
||||
return times != 1
|
||||
return False
|
||||
blockchain.blockchains = {7: {'check': check, 'parent': {'check': lambda x: True}}}
|
||||
self.interface.q.put_nowait({'block_height': 8, 'mock': {'catchup':1, 'check': lambda x: False, 'connect': lambda x: False}})
|
||||
self.interface.q.put_nowait({'block_height': 7, 'mock': {'backward':1, 'check': lambda x: False, 'connect': lambda height: height == 6}})
|
||||
|
@ -108,11 +108,10 @@ class TestNetwork(unittest.TestCase):
|
|||
self.interface.q.put_nowait({'block_height': 4, 'mock': {'binary':1, 'check': lambda x: 1, 'connect': lambda x: False}})
|
||||
self.interface.q.put_nowait({'block_height': 5, 'mock': {'binary':1, 'check': lambda x: 1, 'connect': lambda x: False}})
|
||||
self.interface.q.put_nowait({'block_height': 6, 'mock': {'binary':1, 'check': lambda x: 1, 'connect': lambda x: True}})
|
||||
self.interface.q.put_nowait({'block_height': 7, 'mock': {'binary':1, 'check': lambda x: False, 'connect': lambda x: True}})
|
||||
ifa = self.interface
|
||||
self.assertEqual(('join', 8), asyncio.get_event_loop().run_until_complete(ifa.sync_until(8, next_height=8)))
|
||||
self.assertEqual(('conflict', 8), asyncio.get_event_loop().run_until_complete(ifa.sync_until(8, next_height=7)))
|
||||
self.assertEqual(self.interface.q.qsize(), 0)
|
||||
self.assertEqual(times, 2)
|
||||
self.assertEqual(times, 1)
|
||||
|
||||
if __name__=="__main__":
|
||||
constants.set_regtest()
|
||||
|
|
Loading…
Add table
Reference in a new issue