Compare commits

...

1 commit

Author SHA1 Message Date
Victor Shyba
7885f34221 upgrading latest lbrycrd wip 2019-07-23 12:42:05 -03:00
6 changed files with 62 additions and 7 deletions

View file

@ -214,7 +214,9 @@ class CommandTestCase(IntegrationTestCase):
self.assertEqual(claim['outputs'][0]['name'], name) self.assertEqual(claim['outputs'][0]['name'], name)
if confirm: if confirm:
await self.on_transaction_dict(claim) await self.on_transaction_dict(claim)
height = self.ledger.headers.height
await self.generate(1) await self.generate(1)
await self.on_header(height + 1)
await self.on_transaction_dict(claim) await self.on_transaction_dict(claim)
return claim return claim

View file

@ -2,7 +2,7 @@ __node_daemon__ = 'lbrycrdd'
__node_cli__ = 'lbrycrd-cli' __node_cli__ = 'lbrycrd-cli'
__node_bin__ = '' __node_bin__ = ''
__node_url__ = ( __node_url__ = (
'https://github.com/lbryio/lbrycrd/releases/download/v0.12.4.1/lbrycrd-linux.zip' 'https://github.com/lbryio/lbrycrd/releases/download/v0.17.2.0/lbrycrd-linux.zip'
) )
__spvserver__ = 'lbry.wallet.server.coin.LBCRegTest' __spvserver__ = 'lbry.wallet.server.coin.LBCRegTest'

View file

@ -3,10 +3,11 @@ import logging
from binascii import unhexlify from binascii import unhexlify
from typing import Tuple, List, Dict from typing import Tuple, List, Dict
from lbry.wallet.claim_proofs import verify_proof, InvalidProofError
from torba.client.baseledger import BaseLedger from torba.client.baseledger import BaseLedger
from torba.client.baseaccount import SingleKey from torba.client.baseaccount import SingleKey
from lbry.schema.result import Outputs from lbry.schema.result import Outputs
from lbry.schema.url import URL from lbry.schema.url import URL, normalize_name
from lbry.wallet.dewies import dewies_to_lbc from lbry.wallet.dewies import dewies_to_lbc
from lbry.wallet.resolve import Resolver from lbry.wallet.resolve import Resolver
from lbry.wallet.account import Account from lbry.wallet.account import Account
@ -72,7 +73,50 @@ class MainNetLedger(BaseLedger):
result[url] = txo result[url] = txo
else: else:
result[url] = {'error': f'{url} did not resolve to a claim'} result[url] = {'error': f'{url} did not resolve to a claim'}
return result return await self.validate_resolutions(result)
async def validate_resolutions(self, resolutions: dict):
provables = {}
for url, txo in resolutions.items():
if isinstance(txo, dict) and 'error' in txo:
continue
parsed_url = URL.parse(url)
# cases we check: names without sequence, claim id or any modifier
# except: @channel/name as the signature is enough, instead we check '@channel'
if parsed_url.has_channel:
if not parsed_url.has_stream_in_channel and parsed_url.channel.to_dict().keys() == {'name'}:
provables.setdefault(normalize_name(parsed_url.channel.name), []).append((url, txo.id))
elif parsed_url.has_stream and parsed_url.stream.to_dict().keys() == {'name'}:
provables.setdefault(normalize_name(parsed_url.stream.name), []).append((url, txo.id))
if not provables:
return resolutions
root_hash = self.headers.claim_trie_root.decode()
names = list(provables.keys())
proofs = await self.network.get_name_proofs(self.headers.hash().decode(), *names)
for proof, name in zip(proofs, names):
all_failed = True
for url, txid in provables[name]:
if not proof.get('txhash'):
resolutions[url] = {'error': f"Proof mismatch on {url}: no claims under {name} but we got {txid}"}
continue
expected_txid = f"{proof['txhash']}:{proof['nOut']}"
if txid != expected_txid:
resolutions[url] = {
'error': f"Proof mismatch: {url} resolved to {txid} instead of {expected_txid} on {name}"
}
else:
all_failed = False
if not all_failed:
try:
verify_proof(proof, root_hash, name)
continue
except InvalidProofError as error:
for url, _ in provables[name]:
resolution = resolutions[url]
if isinstance(resolution, dict) and 'error' in resolution:
continue
resolutions[url] = {'error': f'Invalid proof for {url}: {str(error)}'}
return resolutions
async def claim_search(self, **kwargs) -> Tuple[List, int, int]: async def claim_search(self, **kwargs) -> Tuple[List, int, int]:
return await self._inflate_outputs(self.network.claim_search(**kwargs)) return await self._inflate_outputs(self.network.claim_search(**kwargs))

View file

@ -9,5 +9,8 @@ class Network(BaseNetwork):
def resolve(self, urls): def resolve(self, urls):
return self.rpc('blockchain.claimtrie.resolve', urls) return self.rpc('blockchain.claimtrie.resolve', urls)
def get_name_proofs(self, block_hash, *names):
return self.rpc('blockchain.claimtrie.getnameproofs', (block_hash, *names))
def claim_search(self, **kwargs): def claim_search(self, **kwargs):
return self.rpc('blockchain.claimtrie.search', kwargs) return self.rpc('blockchain.claimtrie.search', kwargs)

View file

@ -104,6 +104,7 @@ class LBRYElectrumX(ElectrumX):
'blockchain.transaction.get_height': self.transaction_get_height, 'blockchain.transaction.get_height': self.transaction_get_height,
'blockchain.claimtrie.search': self.claimtrie_search, 'blockchain.claimtrie.search': self.claimtrie_search,
'blockchain.claimtrie.resolve': self.claimtrie_resolve, 'blockchain.claimtrie.resolve': self.claimtrie_resolve,
'blockchain.claimtrie.getnameproofs': self.claimtrie_getnameproofs,
'blockchain.claimtrie.getclaimsbyids': self.claimtrie_getclaimsbyids, 'blockchain.claimtrie.getclaimsbyids': self.claimtrie_getclaimsbyids,
'blockchain.block.get_server_height': self.get_server_height, 'blockchain.block.get_server_height': self.get_server_height,
} }
@ -165,6 +166,9 @@ class LBRYElectrumX(ElectrumX):
async def get_server_height(self): async def get_server_height(self):
return self.bp.height return self.bp.height
def claimtrie_getnameproofs(self, block_hash, *names):
return self.daemon._send_vector('getnameproof', iter((name, block_hash) for name in names))
async def transaction_get_height(self, tx_hash): async def transaction_get_height(self, tx_hash):
self.assert_tx_hash(tx_hash) self.assert_tx_hash(tx_hash)
transaction_info = await self.daemon.getrawtransaction(tx_hash, True) transaction_info = await self.daemon.getrawtransaction(tx_hash, True)

View file

@ -266,6 +266,7 @@ class BlockchainNode:
self.data_path = None self.data_path = None
self.protocol = None self.protocol = None
self.transport = None self.transport = None
self.blockchain_address = None
self._block_expected = 0 self._block_expected = 0
self.hostname = 'localhost' self.hostname = 'localhost'
self.peerport = 9246 + 2 # avoid conflict with default peer port self.peerport = 9246 + 2 # avoid conflict with default peer port
@ -329,7 +330,7 @@ class BlockchainNode:
self.daemon_bin, self.daemon_bin,
f'-datadir={self.data_path}', '-printtoconsole', '-regtest', '-server', '-txindex', f'-datadir={self.data_path}', '-printtoconsole', '-regtest', '-server', '-txindex',
f'-rpcuser={self.rpcuser}', f'-rpcpassword={self.rpcpassword}', f'-rpcport={self.rpcport}', f'-rpcuser={self.rpcuser}', f'-rpcpassword={self.rpcpassword}', f'-rpcport={self.rpcport}',
f'-port={self.peerport}' f'-port={self.peerport}', '-addresstype=legacy', '-vbparams=segwit:0:999999999999'
) )
self.log.info(' '.join(command)) self.log.info(' '.join(command))
self.transport, self.protocol = await loop.subprocess_exec( self.transport, self.protocol = await loop.subprocess_exec(
@ -364,9 +365,10 @@ class BlockchainNode:
self.log.info(out.decode().strip()) self.log.info(out.decode().strip())
return out.decode().strip() return out.decode().strip()
def generate(self, blocks): async def generate(self, blocks, address=None):
self._block_expected += blocks self._block_expected += blocks
return self._cli_cmnd('generate', str(blocks)) address = await self.get_raw_change_address()
return await self._cli_cmnd('generatetoaddress', str(blocks), str(address))
def invalidate_block(self, blockhash): def invalidate_block(self, blockhash):
return self._cli_cmnd('invalidateblock', blockhash) return self._cli_cmnd('invalidateblock', blockhash)
@ -375,7 +377,7 @@ class BlockchainNode:
return self._cli_cmnd('getblockhash', str(block)) return self._cli_cmnd('getblockhash', str(block))
def get_raw_change_address(self): def get_raw_change_address(self):
return self._cli_cmnd('getrawchangeaddress') return self._cli_cmnd('getrawchangeaddress', 'legacy')
async def get_balance(self): async def get_balance(self):
return float(await self._cli_cmnd('getbalance')) return float(await self._cli_cmnd('getbalance'))