fixing a variety of broken tests, updated getclaimbyid usage

This commit is contained in:
Brannon King 2021-11-26 11:45:40 -05:00
parent a719c06615
commit c27d9c50bd
7 changed files with 114 additions and 160 deletions

View file

@ -75,9 +75,9 @@ class Conductor:
await self.lbcd_node.running.wait() await self.lbcd_node.running.wait()
self.lbcd_started = True self.lbcd_started = True
async def stop_lbcd(self): async def stop_lbcd(self, cleanup=True):
if self.lbcd_started: if self.lbcd_started:
await self.lbcd_node.stop(cleanup=True) await self.lbcd_node.stop(cleanup)
self.lbcd_started = False self.lbcd_started = False
async def start_hub(self): async def start_hub(self):
@ -86,9 +86,9 @@ class Conductor:
await self.lbcwallet_node.running.wait() await self.lbcwallet_node.running.wait()
self.hub_started = True self.hub_started = True
async def stop_hub(self): async def stop_hub(self, cleanup=True):
if self.hub_started: if self.hub_started:
await self.hub_node.stop(cleanup=True) await self.hub_node.stop(cleanup)
self.hub_started = False self.hub_started = False
async def start_spv(self): async def start_spv(self):
@ -96,9 +96,9 @@ class Conductor:
await self.spv_node.start(self.lbcwallet_node) await self.spv_node.start(self.lbcwallet_node)
self.spv_started = True self.spv_started = True
async def stop_spv(self): async def stop_spv(self, cleanup=True):
if self.spv_started: if self.spv_started:
await self.spv_node.stop(cleanup=True) await self.spv_node.stop(cleanup)
self.spv_started = False self.spv_started = False
async def start_wallet(self): async def start_wallet(self):
@ -106,25 +106,26 @@ class Conductor:
await self.wallet_node.start(self.spv_node) await self.wallet_node.start(self.spv_node)
self.wallet_started = True self.wallet_started = True
async def stop_wallet(self): async def stop_wallet(self, cleanup=True):
if self.wallet_started: if self.wallet_started:
await self.wallet_node.stop(cleanup=True) await self.wallet_node.stop(cleanup)
self.wallet_started = False self.wallet_started = False
async def start_lbcwallet(self): async def start_lbcwallet(self, clean=True):
if not self.lbcwallet_started: if not self.lbcwallet_started:
asyncio.create_task(self.lbcwallet_node.start()) asyncio.create_task(self.lbcwallet_node.start())
await self.lbcwallet_node.running.wait() await self.lbcwallet_node.running.wait()
mining_addr = await self.lbcwallet_node.get_new_address('default') if clean:
mining_addr = await self.lbcwallet_node.get_new_address()
self.lbcwallet_node.mining_addr = mining_addr self.lbcwallet_node.mining_addr = mining_addr
await self.lbcwallet_node.generate(200) await self.lbcwallet_node.generate(200)
# unlock the wallet for the next 1 hour # unlock the wallet for the next 1 hour
await self.lbcwallet_node.wallet_passphrase("password", 3600) await self.lbcwallet_node.wallet_passphrase("password", 3600)
self.lbcwallet_started = True self.lbcwallet_started = True
async def stop_lbcwallet(self): async def stop_lbcwallet(self, cleanup=True):
if self.lbcwallet_started: if self.lbcwallet_started:
await self.lbcwallet_node.stop(cleanup=True) await self.lbcwallet_node.stop(cleanup)
self.lbcwallet_started = False self.lbcwallet_started = False
async def start(self): async def start(self):
@ -146,6 +147,11 @@ class Conductor:
except Exception as e: except Exception as e:
log.exception('Exception raised while stopping services:', exc_info=e) log.exception('Exception raised while stopping services:', exc_info=e)
async def clear_mempool(self):
await self.stop_lbcwallet(cleanup=False)
await self.stop_lbcd(cleanup=False)
await self.start_lbcd()
await self.start_lbcwallet(clean=False)
class WalletNode: class WalletNode:
@ -166,8 +172,9 @@ class WalletNode:
async def start(self, spv_node: 'SPVNode', seed=None, connect=True, config=None): async def start(self, spv_node: 'SPVNode', seed=None, connect=True, config=None):
wallets_dir = os.path.join(self.data_path, 'wallets') wallets_dir = os.path.join(self.data_path, 'wallets')
os.mkdir(wallets_dir)
wallet_file_name = os.path.join(wallets_dir, 'my_wallet.json') wallet_file_name = os.path.join(wallets_dir, 'my_wallet.json')
if not os.path.isdir(wallets_dir):
os.mkdir(wallets_dir)
with open(wallet_file_name, 'w') as wallet_file: with open(wallet_file_name, 'w') as wallet_file:
wallet_file.write('{"version": 1, "accounts": []}\n') wallet_file.write('{"version": 1, "accounts": []}\n')
self.manager = self.manager_class.from_config({ self.manager = self.manager_class.from_config({
@ -273,6 +280,7 @@ class LBCDProcess(asyncio.SubprocessProtocol):
b'keypool keep', b'keypool keep',
b'keypool reserve', b'keypool reserve',
b'keypool return', b'keypool return',
b'Block submitted',
] ]
def __init__(self): def __init__(self):
@ -326,9 +334,6 @@ class WalletProcess(asyncio.SubprocessProtocol):
class LBCDNode: class LBCDNode:
P2SH_SEGWIT_ADDRESS = "p2sh-segwit"
BECH32_ADDRESS = "bech32"
def __init__(self, url, daemon, cli): def __init__(self, url, daemon, cli):
self.latest_release_url = url self.latest_release_url = url
self.project_dir = os.path.dirname(os.path.dirname(__file__)) self.project_dir = os.path.dirname(os.path.dirname(__file__))
@ -344,9 +349,7 @@ class LBCDNode:
self.rpcport = 29245 self.rpcport = 29245
self.rpcuser = 'rpcuser' self.rpcuser = 'rpcuser'
self.rpcpassword = 'rpcpassword' self.rpcpassword = 'rpcpassword'
self.stopped = False self.stopped = True
self.restart_ready = asyncio.Event()
self.restart_ready.set()
self.running = asyncio.Event() self.running = asyncio.Event()
@property @property
@ -411,11 +414,10 @@ class LBCDNode:
'--txindex', f'--rpcuser={self.rpcuser}', f'--rpcpass={self.rpcpassword}' '--txindex', f'--rpcuser={self.rpcuser}', f'--rpcpass={self.rpcpassword}'
] ]
self.log.info(' '.join(command)) self.log.info(' '.join(command))
while not self.stopped: while self.stopped:
if self.running.is_set(): if self.running.is_set():
await asyncio.sleep(1) await asyncio.sleep(1)
continue continue
await self.restart_ready.wait()
try: try:
self.transport, self.protocol = await loop.subprocess_exec( self.transport, self.protocol = await loop.subprocess_exec(
LBCDProcess, *command LBCDProcess, *command
@ -423,6 +425,7 @@ class LBCDNode:
await self.protocol.ready.wait() await self.protocol.ready.wait()
assert not self.protocol.stopped.is_set() assert not self.protocol.stopped.is_set()
self.running.set() self.running.set()
self.stopped = False
except asyncio.CancelledError: except asyncio.CancelledError:
self.running.clear() self.running.clear()
raise raise
@ -437,24 +440,20 @@ class LBCDNode:
await self.protocol.stopped.wait() await self.protocol.stopped.wait()
self.transport.close() self.transport.close()
finally: finally:
self.log.info("Done shutting down " + self.daemon_bin)
if cleanup: if cleanup:
self.cleanup() self.cleanup()
async def clear_mempool(self):
self.restart_ready.clear()
self.transport.terminate()
await self.protocol.stopped.wait()
self.transport.close()
self.running.clear() self.running.clear()
os.remove(os.path.join(self.data_path, 'regtest', 'mempool.dat'))
self.restart_ready.set()
await self.running.wait()
def cleanup(self): def cleanup(self):
assert self.stopped
shutil.rmtree(self.data_path, ignore_errors=True) shutil.rmtree(self.data_path, ignore_errors=True)
class LBCWalletNode: class LBCWalletNode:
P2SH_SEGWIT_ADDRESS = "p2sh-segwit"
BECH32_ADDRESS = "bech32"
def __init__(self, url, lbcwallet, cli): def __init__(self, url, lbcwallet, cli):
self.latest_release_url = url self.latest_release_url = url
self.project_dir = os.path.dirname(os.path.dirname(__file__)) self.project_dir = os.path.dirname(os.path.dirname(__file__))
@ -470,9 +469,7 @@ class LBCWalletNode:
self.rpcuser = 'rpcuser' self.rpcuser = 'rpcuser'
self.rpcpassword = 'rpcpassword' self.rpcpassword = 'rpcpassword'
self.data_path = tempfile.mkdtemp() self.data_path = tempfile.mkdtemp()
self.stopped = False self.stopped = True
self.restart_ready = asyncio.Event()
self.restart_ready.set()
self.running = asyncio.Event() self.running = asyncio.Event()
self.block_expected = 0 self.block_expected = 0
self.mining_addr = '' self.mining_addr = ''
@ -544,11 +541,10 @@ class LBCWalletNode:
f'--username={self.rpcuser}', f'--password={self.rpcpassword}' f'--username={self.rpcuser}', f'--password={self.rpcpassword}'
] ]
self.log.info(' '.join(command)) self.log.info(' '.join(command))
while not self.stopped: while self.stopped:
if self.running.is_set(): if self.running.is_set():
await asyncio.sleep(1) await asyncio.sleep(1)
continue continue
await self.restart_ready.wait()
try: try:
self.transport, self.protocol = await loop.subprocess_exec( self.transport, self.protocol = await loop.subprocess_exec(
WalletProcess, *command WalletProcess, *command
@ -557,6 +553,7 @@ class LBCWalletNode:
await self.protocol.ready.wait() await self.protocol.ready.wait()
assert not self.protocol.stopped.is_set() assert not self.protocol.stopped.is_set()
self.running.set() self.running.set()
self.stopped = False
except asyncio.CancelledError: except asyncio.CancelledError:
self.running.clear() self.running.clear()
raise raise
@ -565,6 +562,7 @@ class LBCWalletNode:
log.exception('failed to start lbcwallet', exc_info=e) log.exception('failed to start lbcwallet', exc_info=e)
def cleanup(self): def cleanup(self):
assert self.stopped
shutil.rmtree(self.data_path, ignore_errors=True) shutil.rmtree(self.data_path, ignore_errors=True)
async def stop(self, cleanup=True): async def stop(self, cleanup=True):
@ -574,18 +572,10 @@ class LBCWalletNode:
await self.protocol.stopped.wait() await self.protocol.stopped.wait()
self.transport.close() self.transport.close()
finally: finally:
self.log.info("Done shutting down " + self.lbcwallet_bin)
if cleanup: if cleanup:
self.cleanup() self.cleanup()
async def clear_mempool(self):
self.restart_ready.clear()
self.transport.terminate()
await self.protocol.stopped.wait()
self.transport.close()
self.running.clear() self.running.clear()
self.restart_ready.set()
await self.running.wait()
async def _cli_cmnd(self, *args): async def _cli_cmnd(self, *args):
cmnd_args = [ cmnd_args = [
@ -631,8 +621,8 @@ class LBCWalletNode:
def get_raw_change_address(self): def get_raw_change_address(self):
return self._cli_cmnd('getrawchangeaddress') return self._cli_cmnd('getrawchangeaddress')
def get_new_address(self, account): def get_new_address(self, address_type='legacy'):
return self._cli_cmnd('getnewaddress', account) return self._cli_cmnd('getnewaddress', "", address_type)
async def get_balance(self): async def get_balance(self):
return await self._cli_cmnd('getbalance') return await self._cli_cmnd('getbalance')
@ -647,7 +637,10 @@ class LBCWalletNode:
return self._cli_cmnd('createrawtransaction', json.dumps(inputs), json.dumps(outputs)) return self._cli_cmnd('createrawtransaction', json.dumps(inputs), json.dumps(outputs))
async def sign_raw_transaction_with_wallet(self, tx): async def sign_raw_transaction_with_wallet(self, tx):
return json.loads(await self._cli_cmnd('signrawtransactionwithwallet', tx))['hex'].encode() # the "withwallet" portion should only come into play if we are doing segwit.
# and "withwallet" doesn't exist on lbcd yet.
result = await self._cli_cmnd('signrawtransaction', tx)
return json.loads(result)['hex'].encode()
def decode_raw_transaction(self, tx): def decode_raw_transaction(self, tx):
return self._cli_cmnd('decoderawtransaction', hexlify(tx.raw).decode()) return self._cli_cmnd('decoderawtransaction', hexlify(tx.raw).decode())
@ -693,8 +686,6 @@ class HubNode:
self.hostname = 'localhost' self.hostname = 'localhost'
self.rpcport = 50051 # avoid conflict with default rpc port self.rpcport = 50051 # avoid conflict with default rpc port
self.stopped = False self.stopped = False
self.restart_ready = asyncio.Event()
self.restart_ready.set()
self.running = asyncio.Event() self.running = asyncio.Event()
@property @property
@ -751,7 +742,6 @@ class HubNode:
if self.running.is_set(): if self.running.is_set():
await asyncio.sleep(1) await asyncio.sleep(1)
continue continue
await self.restart_ready.wait()
try: try:
if not self.debug: if not self.debug:
self.transport, self.protocol = await loop.subprocess_exec( self.transport, self.protocol = await loop.subprocess_exec(

View file

@ -334,42 +334,7 @@ class LBCDaemon(Daemon):
async def getrawtransaction(self, hex_hash, verbose=False): async def getrawtransaction(self, hex_hash, verbose=False):
return await super().getrawtransaction(hex_hash=hex_hash, verbose=verbose) return await super().getrawtransaction(hex_hash=hex_hash, verbose=verbose)
@handles_errors
async def getclaimbyid(self, claim_id):
'''Given a claim id, retrieves claim information.'''
return await self._send_single('getclaimbyid', (claim_id,))
@handles_errors
async def getclaimsbyids(self, claim_ids):
'''Given a list of claim ids, batches calls to retrieve claim information.'''
return await self._send_vector('getclaimbyid', ((claim_id,) for claim_id in claim_ids))
@handles_errors @handles_errors
async def getclaimsforname(self, name): async def getclaimsforname(self, name):
'''Given a name, retrieves all claims matching that name.''' '''Given a name, retrieves all claims matching that name.'''
return await self._send_single('getclaimsforname', (name,)) return await self._send_single('getclaimsforname', (name,))
@handles_errors
async def getclaimsfortx(self, txid):
'''Given a txid, returns the claims it make.'''
return await self._send_single('getclaimsfortx', (txid,)) or []
@handles_errors
async def getnameproof(self, name, block_hash=None):
'''Given a name and optional block_hash, returns a name proof and winner, if any.'''
return await self._send_single('getnameproof', (name, block_hash,) if block_hash else (name,))
@handles_errors
async def getvalueforname(self, name):
'''Given a name, returns the winning claim value.'''
return await self._send_single('getvalueforname', (name,))
@handles_errors
async def getnamesintrie(self):
'''Given a name, returns the winning claim value.'''
return await self._send_single('getnamesintrie')
@handles_errors
async def claimname(self, name, hexvalue, amount):
'''Claim a name, used for functional tests only.'''
return await self._send_single('claimname', (name, hexvalue, float(amount)))

View file

@ -40,22 +40,17 @@ def checkrecord(record, expected_winner, expected_claim):
async def checkcontrolling(daemon: Daemon, db: SQLDB): async def checkcontrolling(daemon: Daemon, db: SQLDB):
records, claim_ids, names, futs = [], [], [], [] records, names, futs = [], [], []
for record in db.get_claims('claimtrie.claim_hash as is_controlling, claim.*', is_controlling=True): for record in db.get_claims('claimtrie.claim_hash as is_controlling, claim.*', is_controlling=True):
records.append(record) records.append(record)
claim_id = hex_reverted(record['claim_hash']) claim_id = hex_reverted(record['claim_hash'])
claim_ids.append((claim_id,)) names.append((record['normalized'], (claim_id,), "", True)) # last parameter is IncludeValues
names.append((record['normalized'],))
if len(names) > 50000: if len(names) > 50000:
futs.append(daemon._send_vector('getvalueforname', names[:])) futs.append(daemon._send_vector('getclaimsfornamebyid', names))
futs.append(daemon._send_vector('getclaimbyid', claim_ids[:]))
names.clear() names.clear()
claim_ids.clear()
if names: if names:
futs.append(daemon._send_vector('getvalueforname', names[:])) futs.append(daemon._send_vector('getclaimsfornamebyid', names))
futs.append(daemon._send_vector('getclaimbyid', claim_ids[:]))
names.clear() names.clear()
claim_ids.clear()
while futs: while futs:
winners, claims = futs.pop(0), futs.pop(0) winners, claims = futs.pop(0), futs.pop(0)

View file

@ -112,7 +112,7 @@ class BlockchainReorganizationTests(CommandTestCase):
# reorg the last block dropping our claim tx # reorg the last block dropping our claim tx
await self.blockchain.invalidate_block(invalidated_block_hash) await self.blockchain.invalidate_block(invalidated_block_hash)
await self.blockchain.clear_mempool() await self.conductor.clear_mempool()
await self.blockchain.generate(2) await self.blockchain.generate(2)
# wait for the client to catch up and verify the reorg # wait for the client to catch up and verify the reorg
@ -191,7 +191,7 @@ class BlockchainReorganizationTests(CommandTestCase):
# reorg the last block dropping our claim tx # reorg the last block dropping our claim tx
await self.blockchain.invalidate_block(invalidated_block_hash) await self.blockchain.invalidate_block(invalidated_block_hash)
await self.blockchain.clear_mempool() await self.conductor.clear_mempool()
await self.blockchain.generate(2) await self.blockchain.generate(2)
# wait for the client to catch up and verify the reorg # wait for the client to catch up and verify the reorg

View file

@ -58,15 +58,15 @@ class WalletCommands(CommandTestCase):
self.assertEqual(status['wallet']['servers'][0]['port'], 54320) self.assertEqual(status['wallet']['servers'][0]['port'], 54320)
async def test_sending_to_scripthash_address(self): async def test_sending_to_scripthash_address(self):
self.assertEqual(await self.blockchain.get_balance(), '95.99973580') bal = await self.blockchain.get_balance()
await self.assertBalance(self.account, '10.0') await self.assertBalance(self.account, '10.0')
p2sh_address1 = await self.blockchain.get_new_address(self.blockchain.P2SH_SEGWIT_ADDRESS) p2sh_address1 = await self.blockchain.get_new_address(self.blockchain.P2SH_SEGWIT_ADDRESS)
tx = await self.account_send('2.0', p2sh_address1) tx = await self.account_send('2.0', p2sh_address1)
self.assertEqual(tx['outputs'][0]['address'], p2sh_address1) self.assertEqual(tx['outputs'][0]['address'], p2sh_address1)
self.assertEqual(await self.blockchain.get_balance(), '98.99973580') # +1 lbc for confirm block self.assertEqual(await self.blockchain.get_balance(), str(float(bal)+3)) # +1 lbc for confirm block
await self.assertBalance(self.account, '7.999877') await self.assertBalance(self.account, '7.999877')
await self.wallet_send('3.0', p2sh_address1) await self.wallet_send('3.0', p2sh_address1)
self.assertEqual(await self.blockchain.get_balance(), '102.99973580') # +1 lbc for confirm block self.assertEqual(await self.blockchain.get_balance(), str(float(bal)+7)) # +1 lbc for confirm block
await self.assertBalance(self.account, '4.999754') await self.assertBalance(self.account, '4.999754')
async def test_balance_caching(self): async def test_balance_caching(self):

View file

@ -31,13 +31,13 @@ class BaseResolveTestCase(CommandTestCase):
self.assertEqual(claim_from_es['effective_amount'], claim_from_db.effective_amount) self.assertEqual(claim_from_es['effective_amount'], claim_from_db.effective_amount)
def assertMatchDBClaim(self, expected, claim): def assertMatchDBClaim(self, expected, claim):
self.assertEqual(expected['claimId'], claim.claim_hash.hex()) self.assertEqual(expected['claimid'], claim.claim_hash.hex())
self.assertEqual(expected['validAtHeight'], claim.activation_height) self.assertEqual(expected['validatheight'], claim.activation_height)
self.assertEqual(expected['lastTakeoverHeight'], claim.last_takeover_height) self.assertEqual(expected['lasttakeoverheight'], claim.last_takeover_height)
self.assertEqual(expected['txId'], claim.tx_hash[::-1].hex()) self.assertEqual(expected['txid'], claim.tx_hash[::-1].hex())
self.assertEqual(expected['n'], claim.position) self.assertEqual(expected['n'], claim.position)
self.assertEqual(expected['amount'], claim.amount) self.assertEqual(expected['amount'], claim.amount)
self.assertEqual(expected['effectiveAmount'], claim.effective_amount) self.assertEqual(expected['effectiveamount'], claim.effective_amount)
async def assertResolvesToClaimId(self, name, claim_id): async def assertResolvesToClaimId(self, name, claim_id):
other = await self.resolve(name) other = await self.resolve(name)
@ -53,9 +53,10 @@ class BaseResolveTestCase(CommandTestCase):
self.assertEqual(claim_id, claim_from_es[0][0]['claim_hash'][::-1].hex()) self.assertEqual(claim_id, claim_from_es[0][0]['claim_hash'][::-1].hex())
async def assertNoClaimForName(self, name: str): async def assertNoClaimForName(self, name: str):
lbrycrd_winning = json.loads(await self.blockchain._cli_cmnd('getvalueforname', name)) lbrycrd_winning = json.loads(await self.blockchain._cli_cmnd('getclaimsforname', name))
stream, channel, _, _ = await self.conductor.spv_node.server.bp.db.resolve(name) stream, channel, _, _ = await self.conductor.spv_node.server.bp.db.resolve(name)
self.assertNotIn('claimId', lbrycrd_winning) if 'claims' in lbrycrd_winning and lbrycrd_winning['claims'] is not None:
self.assertEqual(len(lbrycrd_winning['claims']), 0)
if stream is not None: if stream is not None:
self.assertIsInstance(stream, LookupError) self.assertIsInstance(stream, LookupError)
else: else:
@ -63,20 +64,23 @@ class BaseResolveTestCase(CommandTestCase):
claim_from_es = await self.conductor.spv_node.server.bp.db.search_index.search(name=name) claim_from_es = await self.conductor.spv_node.server.bp.db.search_index.search(name=name)
self.assertListEqual([], claim_from_es[0]) self.assertListEqual([], claim_from_es[0])
async def assertNoClaim(self, claim_id: str): async def assertNoClaim(self, name: str, claim_id: str):
self.assertDictEqual( expected = json.loads(await self.blockchain._cli_cmnd('getclaimsfornamebyid', name, '["' + claim_id + '"]'))
{}, json.loads(await self.blockchain._cli_cmnd('getclaimbyid', claim_id)) if 'claims' in expected and expected['claims'] is not None:
) # ensure that if we do have the matching claim that it is not active
self.assertEqual(expected['claims'][0]['effectiveamount'], 0)
claim_from_es = await self.conductor.spv_node.server.bp.db.search_index.search(claim_id=claim_id) claim_from_es = await self.conductor.spv_node.server.bp.db.search_index.search(claim_id=claim_id)
self.assertListEqual([], claim_from_es[0]) self.assertListEqual([], claim_from_es[0])
claim = await self.conductor.spv_node.server.bp.db.fs_getclaimbyid(claim_id) claim = await self.conductor.spv_node.server.bp.db.fs_getclaimbyid(claim_id)
self.assertIsNone(claim) self.assertIsNone(claim)
async def assertMatchWinningClaim(self, name): async def assertMatchWinningClaim(self, name):
expected = json.loads(await self.blockchain._cli_cmnd('getvalueforname', name)) expected = json.loads(await self.blockchain._cli_cmnd('getclaimsfornamebybid', name, "[0]"))
stream, channel, _, _ = await self.conductor.spv_node.server.bp.db.resolve(name) stream, channel, _, _ = await self.conductor.spv_node.server.bp.db.resolve(name)
claim = stream if stream else channel claim = stream if stream else channel
await self._assertMatchClaim(expected, claim) expected['claims'][0]['lasttakeoverheight'] = expected['lasttakeoverheight']
await self._assertMatchClaim(expected['claims'][0], claim)
return claim return claim
async def _assertMatchClaim(self, expected, claim): async def _assertMatchClaim(self, expected, claim):
@ -86,28 +90,31 @@ class BaseResolveTestCase(CommandTestCase):
) )
self.assertEqual(len(claim_from_es[0]), 1) self.assertEqual(len(claim_from_es[0]), 1)
self.assertMatchESClaim(claim_from_es[0][0], claim) self.assertMatchESClaim(claim_from_es[0][0], claim)
self._check_supports(claim.claim_hash.hex(), expected['supports'], claim_from_es[0][0]['support_amount']) self._check_supports(claim.claim_hash.hex(), expected.get('supports', []),
claim_from_es[0][0]['support_amount'], expected['effectiveamount'] > 0)
async def assertMatchClaim(self, claim_id, is_active_in_lbrycrd=True): async def assertMatchClaim(self, name, claim_id, is_active_in_lbrycrd=True):
expected = json.loads(await self.blockchain._cli_cmnd('getclaimbyid', claim_id))
claim = await self.conductor.spv_node.server.bp.db.fs_getclaimbyid(claim_id) claim = await self.conductor.spv_node.server.bp.db.fs_getclaimbyid(claim_id)
if is_active_in_lbrycrd:
if not expected:
self.assertIsNone(claim)
return
self.assertMatchDBClaim(expected, claim)
else:
self.assertDictEqual({}, expected)
claim_from_es = await self.conductor.spv_node.server.bp.db.search_index.search( claim_from_es = await self.conductor.spv_node.server.bp.db.search_index.search(
claim_id=claim.claim_hash.hex() claim_id=claim.claim_hash.hex()
) )
self.assertEqual(len(claim_from_es[0]), 1) self.assertEqual(len(claim_from_es[0]), 1)
self.assertEqual(claim_from_es[0][0]['claim_hash'][::-1].hex(), claim.claim_hash.hex()) self.assertEqual(claim_from_es[0][0]['claim_hash'][::-1].hex(), claim.claim_hash.hex())
self.assertMatchESClaim(claim_from_es[0][0], claim) self.assertMatchESClaim(claim_from_es[0][0], claim)
self._check_supports(
claim.claim_hash.hex(), expected.get('supports', []), claim_from_es[0][0]['support_amount'], expected = json.loads(await self.blockchain._cli_cmnd('getclaimsfornamebyid', name, '["' + claim_id + '"]'))
is_active_in_lbrycrd if is_active_in_lbrycrd:
) if not expected:
self.assertIsNone(claim)
return
expected['claims'][0]['lasttakeoverheight'] = expected['lasttakeoverheight']
self.assertMatchDBClaim(expected['claims'][0], claim)
self._check_supports(claim.claim_hash.hex(), expected['claims'][0].get('supports', []),
claim_from_es[0][0]['support_amount'], is_active_in_lbrycrd)
else:
if 'claims' in expected and expected['claims'] is not None:
# ensure that if we do have the matching claim that it is not active
self.assertEqual(expected['claims'][0]['effectiveamount'], 0)
return claim return claim
async def assertMatchClaimIsWinning(self, name, claim_id): async def assertMatchClaimIsWinning(self, name, claim_id):
@ -122,34 +129,31 @@ class BaseResolveTestCase(CommandTestCase):
total_amount += amount total_amount += amount
if is_active_in_lbrycrd: if is_active_in_lbrycrd:
support = lbrycrd_supports[i] support = lbrycrd_supports[i]
self.assertEqual(support['txId'], db.prefix_db.tx_hash.get(tx_num, deserialize_value=False)[::-1].hex()) self.assertEqual(support['txid'], db.prefix_db.tx_hash.get(tx_num, deserialize_value=False)[::-1].hex())
self.assertEqual(support['n'], position) self.assertEqual(support['n'], position)
self.assertEqual(support['height'], bisect_right(db.tx_counts, tx_num)) self.assertEqual(support['height'], bisect_right(db.tx_counts, tx_num))
self.assertEqual(support['validAtHeight'], db.get_activation(tx_num, position, is_support=True)) self.assertEqual(support['validatheight'], db.get_activation(tx_num, position, is_support=True))
self.assertEqual(total_amount, es_support_amount, f"lbrycrd support amount: {total_amount} vs es: {es_support_amount}") self.assertEqual(total_amount, es_support_amount, f"lbrycrd support amount: {total_amount} vs es: {es_support_amount}")
async def assertMatchClaimsForName(self, name): async def assertMatchClaimsForName(self, name):
expected = json.loads(await self.blockchain._cli_cmnd('getclaimsforname', name)) expected = json.loads(await self.blockchain._cli_cmnd('getclaimsforname', name, "", "true"))
db = self.conductor.spv_node.server.bp.db db = self.conductor.spv_node.server.bp.db
# self.assertEqual(len(expected['claims']), len(db_claims.claims))
# self.assertEqual(expected['lastTakeoverHeight'], db_claims.lastTakeoverHeight)
last_takeover = json.loads(await self.blockchain._cli_cmnd('getvalueforname', name))['lastTakeoverHeight']
for c in expected['claims']: for c in expected['claims']:
c['lastTakeoverHeight'] = last_takeover c['lasttakeoverheight'] = expected['lasttakeoverheight']
claim_id = c['claimId'] claim_id = c['claimid']
claim_hash = bytes.fromhex(claim_id) claim_hash = bytes.fromhex(claim_id)
claim = db._fs_get_claim_by_hash(claim_hash) claim = db._fs_get_claim_by_hash(claim_hash)
self.assertMatchDBClaim(c, claim) self.assertMatchDBClaim(c, claim)
claim_from_es = await self.conductor.spv_node.server.bp.db.search_index.search( claim_from_es = await self.conductor.spv_node.server.bp.db.search_index.search(
claim_id=c['claimId'] claim_id=claim_id
) )
self.assertEqual(len(claim_from_es[0]), 1) self.assertEqual(len(claim_from_es[0]), 1)
self.assertEqual(claim_from_es[0][0]['claim_hash'][::-1].hex(), c['claimId']) self.assertEqual(claim_from_es[0][0]['claim_hash'][::-1].hex(), claim_id)
self.assertMatchESClaim(claim_from_es[0][0], claim) self.assertMatchESClaim(claim_from_es[0][0], claim)
self._check_supports(c['claimId'], c['supports'], claim_from_es[0][0]['support_amount']) self._check_supports(claim_id, c.get('supports', []),
claim_from_es[0][0]['support_amount'], c['effectiveamount'] > 0)
class ResolveCommand(BaseResolveTestCase): class ResolveCommand(BaseResolveTestCase):
@ -262,13 +266,13 @@ class ResolveCommand(BaseResolveTestCase):
self.assertEqual(claim['confirmations'], json.loads(tx_details)['confirmations']) self.assertEqual(claim['confirmations'], json.loads(tx_details)['confirmations'])
# resolve handles invalid data # resolve handles invalid data
await self.blockchain_claim_name("gibberish", hexlify(b"{'invalid':'json'}").decode(), "0.1") # await self.blockchain_claim_name("gibberish", hexlify(b"{'invalid':'json'}").decode(), "0.1")
await self.generate(1) # await self.generate(1)
response = await self.out(self.daemon.jsonrpc_resolve("lbry://gibberish")) # response = await self.out(self.daemon.jsonrpc_resolve("lbry://gibberish"))
self.assertSetEqual({'lbry://gibberish'}, set(response)) # self.assertSetEqual({'lbry://gibberish'}, set(response))
claim = response['lbry://gibberish'] # claim = response['lbry://gibberish']
self.assertEqual(claim['name'], 'gibberish') # self.assertEqual(claim['name'], 'gibberish')
self.assertNotIn('value', claim) # self.assertNotIn('value', claim)
# resolve retries # resolve retries
await self.conductor.spv_node.stop() await self.conductor.spv_node.stop()
@ -646,7 +650,7 @@ class ResolveClaimTakeovers(BaseResolveTestCase):
self.assertEqual(height, self.conductor.spv_node.server.bp.db.db_height) self.assertEqual(height, self.conductor.spv_node.server.bp.db.db_height)
await self.assertMatchClaimIsWinning(name, winning_claim_id) await self.assertMatchClaimIsWinning(name, winning_claim_id)
for non_winning in non_winning_claims: for non_winning in non_winning_claims:
claim = await self.assertMatchClaim( claim = await self.assertMatchClaim(name,
non_winning.claim_id, is_active_in_lbrycrd=non_winning.active_in_lbrycrd non_winning.claim_id, is_active_in_lbrycrd=non_winning.active_in_lbrycrd
) )
self.assertEqual(non_winning.activation_height, claim.activation_height) self.assertEqual(non_winning.activation_height, claim.activation_height)
@ -1334,7 +1338,7 @@ class ResolveClaimTakeovers(BaseResolveTestCase):
await self.generate(1) await self.generate(1)
await self.assertMatchClaim(first_claim_id) await self.assertMatchClaim(name, first_claim_id)
await self.assertMatchClaimIsWinning(name, second_claim_id) await self.assertMatchClaimIsWinning(name, second_claim_id)
async def test_remove_controlling_support(self): async def test_remove_controlling_support(self):
@ -1405,12 +1409,12 @@ class ResolveClaimTakeovers(BaseResolveTestCase):
await self.generate(32) await self.generate(32)
second_claim_id = (await self.stream_create(name, '0.01', allow_duplicate_name=True))['outputs'][0]['claim_id'] second_claim_id = (await self.stream_create(name, '0.01', allow_duplicate_name=True))['outputs'][0]['claim_id']
await self.assertNoClaim(second_claim_id) await self.assertNoClaim(name, second_claim_id)
self.assertEqual( self.assertEqual(
len((await self.conductor.spv_node.server.bp.db.search_index.search(claim_name=name))[0]), 1 len((await self.conductor.spv_node.server.bp.db.search_index.search(claim_name=name))[0]), 1
) )
await self.generate(1) await self.generate(1)
await self.assertMatchClaim(second_claim_id) await self.assertMatchClaim(name, second_claim_id)
self.assertEqual( self.assertEqual(
len((await self.conductor.spv_node.server.bp.db.search_index.search(claim_name=name))[0]), 2 len((await self.conductor.spv_node.server.bp.db.search_index.search(claim_name=name))[0]), 2
) )
@ -1570,7 +1574,7 @@ class ResolveAfterReorg(BaseResolveTestCase):
# reorg the last block dropping our claim tx # reorg the last block dropping our claim tx
await self.blockchain.invalidate_block(invalidated_block_hash) await self.blockchain.invalidate_block(invalidated_block_hash)
await self.blockchain.clear_mempool() await self.conductor.clear_mempool()
await self.blockchain.generate(2) await self.blockchain.generate(2)
# wait for the client to catch up and verify the reorg # wait for the client to catch up and verify the reorg
@ -1649,7 +1653,7 @@ class ResolveAfterReorg(BaseResolveTestCase):
# reorg the last block dropping our claim tx # reorg the last block dropping our claim tx
await self.blockchain.invalidate_block(invalidated_block_hash) await self.blockchain.invalidate_block(invalidated_block_hash)
await self.blockchain.clear_mempool() await self.conductor.clear_mempool()
await self.blockchain.generate(2) await self.blockchain.generate(2)
# wait for the client to catch up and verify the reorg # wait for the client to catch up and verify the reorg

View file

@ -60,7 +60,7 @@ class TestSegwit(CommandTestCase):
tx = await self.blockchain.create_raw_transaction([ tx = await self.blockchain.create_raw_transaction([
{"txid": p2sh_txid1, "vout": 0}, {"txid": p2sh_txid1, "vout": 0},
{"txid": bech32_txid1, "vout": 0}, {"txid": bech32_txid1, "vout": 0},
], [{p2sh_address3: '1.9'}] ], {p2sh_address3: 1.9}
) )
tx = await self.blockchain.sign_raw_transaction_with_wallet(tx) tx = await self.blockchain.sign_raw_transaction_with_wallet(tx)
p2sh_txid3 = await self.blockchain.send_raw_transaction(tx) p2sh_txid3 = await self.blockchain.send_raw_transaction(tx)
@ -71,7 +71,7 @@ class TestSegwit(CommandTestCase):
tx = await self.blockchain.create_raw_transaction([ tx = await self.blockchain.create_raw_transaction([
{"txid": p2sh_txid2, "vout": 0}, {"txid": p2sh_txid2, "vout": 0},
{"txid": bech32_txid2, "vout": 0}, {"txid": bech32_txid2, "vout": 0},
], [{bech32_address3: '1.9'}] ], {bech32_address3: 1.9}
) )
tx = await self.blockchain.sign_raw_transaction_with_wallet(tx) tx = await self.blockchain.sign_raw_transaction_with_wallet(tx)
bech32_txid3 = await self.blockchain.send_raw_transaction(tx) bech32_txid3 = await self.blockchain.send_raw_transaction(tx)
@ -83,7 +83,7 @@ class TestSegwit(CommandTestCase):
tx = await self.blockchain.create_raw_transaction([ tx = await self.blockchain.create_raw_transaction([
{"txid": p2sh_txid3, "vout": 0}, {"txid": p2sh_txid3, "vout": 0},
{"txid": bech32_txid3, "vout": 0}, {"txid": bech32_txid3, "vout": 0},
], [{address: '3.5'}] ], {address: 3.5}
) )
tx = await self.blockchain.sign_raw_transaction_with_wallet(tx) tx = await self.blockchain.sign_raw_transaction_with_wallet(tx)
txid = await self.blockchain.send_raw_transaction(tx) txid = await self.blockchain.send_raw_transaction(tx)