Exemplo n.º 1
0
    def test_validate_what_cant_be_serialized_back_even_by_loading_back_from_dictionary(
            self):
        cert = ClaimDict.generate_certificate(secp256k1_private_key,
                                              curve=SECP256k1)
        self.assertDictEqual(cert.claim_dict, secp256k1_cert)
        original = ClaimDict.load_dict(example_010).serialized
        altered = original + b'\x00\x01\x02\x30\x50\x80\x99'  # pretend this extra trash is from some unknown protobuf

        # manually sign
        signer = get_signer(SECP256k1).load_pem(secp256k1_private_key)
        signature = signer.sign(
            b'example',
            decode_address(claim_address_2),
            altered,
            binascii.unhexlify(claim_id_1),
        )
        detached_sig = Signature(
            NAMED_SECP256K1(signature, binascii.unhexlify(claim_id_1),
                            altered))

        signed = detached_sig.serialized
        self.assertEqual(signed[85:], altered)
        signed_copy = ClaimDict.deserialize(signed)
        signed_copy = ClaimDict.load_dict(signed_copy.claim_dict)
        self.assertEqual(
            signed_copy.validate_signature(claim_address_2,
                                           cert,
                                           name='example'), True)
        self.assertEqual(signed, signed_copy.serialized)
Exemplo n.º 2
0
 def test_fail_to_validate_ecdsa_sig_for_altered_claim(self):
     cert = ClaimDict.generate_certificate(secp256k1_private_key, curve=SECP256k1)
     altered = ClaimDict.load_dict(example_010).sign(secp256k1_private_key, claim_address_1,
                                                     claim_id_1, curve=SECP256k1)
     sd_hash = altered['stream']['source']['source']
     altered['stream']['source']['source'] = sd_hash[::-1]
     altered_copy = ClaimDict.load_dict(altered.claim_dict)
     self.assertRaises(ecdsa.keys.BadSignatureError, altered_copy.validate_signature,
                       claim_address_1, cert)
Exemplo n.º 3
0
 async def claim_name(self,
                      account,
                      name,
                      amount,
                      claim_dict,
                      certificate=None,
                      claim_address=None):
     claim = ClaimDict.load_dict(claim_dict)
     if not claim_address:
         claim_address = await account.receiving.get_or_create_usable_address(
         )
     if certificate:
         claim = claim.sign(certificate.private_key,
                            claim_address,
                            certificate.claim_id,
                            curve=SECP256k1)
     existing_claims = await account.get_claims(claim_name=name)
     if len(existing_claims) == 0:
         tx = await Transaction.claim(name, claim, amount, claim_address,
                                      [account], account)
     elif len(existing_claims) == 1:
         tx = await Transaction.update(existing_claims[0], claim, amount,
                                       claim_address, [account], account)
     else:
         raise NameError(
             f"More than one other claim exists with the name '{name}'.")
     await account.ledger.broadcast(tx)
     await self.old_db.save_claims([
         self._old_get_temp_claim_info(tx, tx.outputs[0], claim_address,
                                       claim_dict, name, amount)
     ]).asFuture(asyncio.get_event_loop())
     # TODO: release reserved tx outputs in case anything fails by this point
     return tx
Exemplo n.º 4
0
    async def download_stream_from_claim(self, node: 'Node', claim_info: typing.Dict,
                                         file_name: typing.Optional[str] = None,
                                         timeout: typing.Optional[float] = 60,
                                         fee_amount: typing.Optional[float] = 0.0,
                                         fee_address: typing.Optional[str] = None,
                                         should_pay: typing.Optional[bool] = True) -> typing.Optional[ManagedStream]:
        claim = ClaimDict.load_dict(claim_info['value'])
        sd_hash = claim.source_hash.decode()
        if sd_hash in self.starting_streams:
            return await self.starting_streams[sd_hash]
        already_started = tuple(filter(lambda s: s.descriptor.sd_hash == sd_hash, self.streams))
        if already_started:
            return already_started[0]
        if should_pay and fee_address and fee_amount and fee_amount > await self.wallet.default_account.get_balance():
            raise Exception("not enough funds")

        self.starting_streams[sd_hash] = asyncio.Future(loop=self.loop)
        stream_task = self.loop.create_task(
            self._download_stream_from_claim(node, self.config.download_dir, claim_info, file_name)
        )
        try:
            await asyncio.wait_for(stream_task, timeout or self.config.download_timeout)
            stream = await stream_task
            self.starting_streams[sd_hash].set_result(stream)
            if should_pay and fee_address and fee_amount:
                await self.wallet.send_amount_to_address(lbc_to_dewies(str(fee_amount)), fee_address.encode('latin1'))
            return stream
        except (asyncio.TimeoutError, asyncio.CancelledError):
            return
        finally:
            if sd_hash in self.starting_streams:
                del self.starting_streams[sd_hash]
Exemplo n.º 5
0
 def test_validate_ecdsa_signature(self):
     cert = ClaimDict.generate_certificate(nist384p_private_key, curve=NIST384p)
     signed = ClaimDict.load_dict(example_010).sign(nist384p_private_key,
                                                    claim_address_2, claim_id_1, curve=NIST384p)
     self.assertDictEqual(signed.claim_dict, claim_010_signed_nist384p)
     signed_copy = ClaimDict.load_protobuf(signed.protobuf)
     self.assertEqual(signed_copy.validate_signature(claim_address_2, cert), True)
Exemplo n.º 6
0
def smart_decode(claim_value):
    """
    Decode a claim value

    Try decoding claim protobuf, if this fails try decoding json and migrating it.
    If unable to decode or migrate, raise DecodeError
    """

    # if already decoded, return
    if isinstance(claim_value, ClaimDict):
        return claim_value
    elif isinstance(claim_value, dict):
        return ClaimDict.load_dict(claim_value)

    try:
        claim_value = binascii.unhexlify(claim_value)
    except (TypeError, ValueError):
        pass

    if claim_value[0] in ['{', ord('{')]:
        try:
            if six.PY3 and isinstance(claim_value, six.binary_type):
                claim_value = claim_value.decode()
            decoded_json = json.loads(claim_value)
            return migrate_json_claim_value(decoded_json)
        except (ValueError, TypeError):
            pass
    try:
        if six.PY3 and isinstance(claim_value, six.text_type):
            claim_value = claim_value.encode()
        return ClaimDict.deserialize(claim_value)
    except (DecodeError, InvalidAddress, KeyError, TypeError):
            raise DecodeError(claim_value)
Exemplo n.º 7
0
    async def test_new_signature_model(self):
        address1, address2 = await self.account.receiving.get_addresses(
            limit=2, only_usable=True)
        sendtxid1 = await self.blockchain.send_to_address(address1, 5)
        sendtxid2 = await self.blockchain.send_to_address(address2, 5)
        await self.blockchain.generate(1)
        await asyncio.wait([
            self.on_transaction_id(sendtxid1),
            self.on_transaction_id(sendtxid2)
        ])

        self.assertEqual(d2l(await self.account.get_balance()), '10.0')

        cert, key = generate_certificate()
        cert_tx = await Transaction.claim('@bar', cert, l2d('1.0'), address1,
                                          [self.account], self.account)
        claim = ClaimDict.load_dict(example_claim_dict)
        claim = claim.sign(key,
                           address1,
                           cert_tx.outputs[0].claim_id,
                           name='foo',
                           curve=SECP256k1,
                           force_detached=True)
        claim_tx = await Transaction.claim('foo', claim, l2d('1.0'), address1,
                                           [self.account], self.account)

        await self.broadcast(cert_tx)
        await self.broadcast(claim_tx)
        await self.ledger.wait(claim_tx)
        await self.blockchain.generate(1)
        await self.ledger.wait(claim_tx)

        response = await self.ledger.resolve(0, 10, 'lbry://@bar/foo')
        self.assertIn('lbry://@bar/foo', response)
        self.assertIn('claim', response['lbry://@bar/foo'])
Exemplo n.º 8
0
 def test_remove_signature_equals_unsigned(self):
     unsigned = ClaimDict.load_dict(example_010)
     signed = unsigned.sign(secp256k1_private_key,
                            claim_address_1,
                            claim_id_1,
                            curve=SECP256k1)
     self.assertEqual(unsigned.serialized, signed.serialized_no_signature)
Exemplo n.º 9
0
    def test_successful_send_name_claim(self):
        expected_claim_out = {
            "claim_id": "f43dc06256a69988bdbea09a58c80493ba15dcfa",
            "fee": "0.00012",
            "nout": 0,
            "success": True,
            "txid":
            "6f8180002ef4d21f5b09ca7d9648a54d213c666daf8639dc283e2fd47450269e",
            "value":
            ClaimDict.load_dict(test_claim_dict).serialized.encode('hex'),
            "claim_address": "",
            "channel_claim_id": "",
            "channel_name": ""
        }

        def success_send_name_claim(self,
                                    name,
                                    val,
                                    amount,
                                    certificate_id=None,
                                    claim_address=None,
                                    change_address=None):
            return defer.succeed(expected_claim_out)

        self.wallet._send_name_claim = success_send_name_claim
        claim_out = yield self.wallet.claim_name('test', 1, test_claim_dict)
        self.assertNotIn('success', claim_out)
        self.assertEqual(expected_claim_out['claim_id'], claim_out['claim_id'])
        self.assertEqual(expected_claim_out['fee'], claim_out['fee'])
        self.assertEqual(expected_claim_out['nout'], claim_out['nout'])
        self.assertEqual(expected_claim_out['txid'], claim_out['txid'])
        self.assertEqual(expected_claim_out['value'], claim_out['value'])
Exemplo n.º 10
0
 def test_alpha2(self):
     prefixes = [
         'en', 'aa', 'ab', 'ae', 'af', 'ak', 'am', 'an', 'ar', 'as', 'av',
         'ay', 'az', 'ba', 'be', 'bg', 'bh', 'bi', 'bm', 'bn', 'bo', 'br',
         'bs', 'ca', 'ce', 'ch', 'co', 'cr', 'cs', 'cu', 'cv', 'cy', 'da',
         'de', 'dv', 'dz', 'ee', 'el', 'eo', 'es', 'et', 'eu', 'fa', 'ff',
         'fi', 'fj', 'fo', 'fr', 'fy', 'ga', 'gd', 'gl', 'gn', 'gu', 'gv',
         'ha', 'he', 'hi', 'ho', 'hr', 'ht', 'hu', 'hy', 'hz', 'ia', 'id',
         'ie', 'ig', 'ii', 'ik', 'io', 'is', 'it', 'iu', 'ja', 'jv', 'ka',
         'kg', 'ki', 'kj', 'kk', 'kl', 'km', 'kn', 'ko', 'kr', 'ks', 'ku',
         'kv', 'kw', 'ky', 'la', 'lb', 'lg', 'li', 'ln', 'lo', 'lt', 'lu',
         'lv', 'mg', 'mh', 'mi', 'mk', 'ml', 'mn', 'mr', 'ms', 'mt', 'my',
         'na', 'nb', 'nd', 'ne', 'ng', 'nl', 'nn', 'no', 'nr', 'nv', 'ny',
         'oc', 'oj', 'om', 'or', 'os', 'pa', 'pi', 'pl', 'ps', 'pt', 'qu',
         'rm', 'rn', 'ro', 'ru', 'rw', 'sa', 'sc', 'sd', 'se', 'sg', 'si',
         'sk', 'sl', 'sm', 'sn', 'so', 'sq', 'sr', 'ss', 'st', 'su', 'sv',
         'sw', 'ta', 'te', 'tg', 'th', 'ti', 'tk', 'tl', 'tn', 'to', 'tr',
         'ts', 'tt', 'tw', 'ty', 'ug', 'uk', 'ur', 'uz', 've', 'vi', 'vo',
         'wa', 'wo', 'xh', 'yi', 'yo', 'za', 'zh', 'zu'
     ]
     for prefix in prefixes:
         metadata = deepcopy(example_010)
         metadata['stream']['metadata']['language'] = prefix
         claim = ClaimDict.load_dict(metadata)
         serialized = claim.serialized
         self.assertDictEqual(
             metadata, dict(ClaimDict.deserialize(serialized).claim_dict))
Exemplo n.º 11
0
 def test_encode_decode(self):
     test_claim = ClaimDict.load_dict(example_010)
     self.assertEqual(test_claim.is_certificate, False)
     self.assertDictEqual(test_claim.claim_dict, example_010)
     test_pb = test_claim.protobuf
     self.assertDictEqual(ClaimDict.load_protobuf(test_pb).claim_dict, example_010)
     self.assertEqual(test_pb.ByteSize(), ClaimDict.load_protobuf(test_pb).protobuf_len)
     self.assertEqual(test_claim.json_len, ClaimDict.load_protobuf(test_pb).json_len)
Exemplo n.º 12
0
 def test_fail_to_validate_with_no_claim_address(self):
     cert = ClaimDict.generate_certificate(secp256k1_private_key, curve=SECP256k1)
     self.assertDictEqual(cert.claim_dict, secp256k1_cert)
     signed = ClaimDict.load_dict(example_010).sign(secp256k1_private_key, claim_address_2,
                                                    claim_id_1, curve=SECP256k1)
     self.assertDictEqual(signed.claim_dict, claim_010_signed_secp256k1)
     signed_copy = ClaimDict.load_protobuf(signed.protobuf)
     self.assertRaises(Exception, signed_copy.validate_signature, None, cert)
Exemplo n.º 13
0
 def test_fail_to_validate_fake_ecdsa_signature(self):
     signed = ClaimDict.load_dict(example_010).sign(secp256k1_private_key, claim_address_1,
                                                    claim_id_1, curve=SECP256k1)
     signed_copy = ClaimDict.load_protobuf(signed.protobuf)
     fake_key = get_signer(SECP256k1).generate().private_key.to_pem()
     fake_cert = ClaimDict.generate_certificate(fake_key, curve=SECP256k1)
     self.assertRaises(ecdsa.keys.BadSignatureError, signed_copy.validate_signature,
                       claim_address_2, fake_cert)
Exemplo n.º 14
0
 def test_validate_ecdsa_signature(self):
     cert = ClaimDict.generate_certificate(secp256k1_private_key, curve=SECP256k1)
     self.assertDictEqual(cert.claim_dict, secp256k1_cert)
     signed = ClaimDict.load_dict(example_010).sign(secp256k1_private_key, claim_address_2,
                                                    claim_id_1, curve=SECP256k1)
     self.assertDictEqual(signed.claim_dict, claim_010_signed_secp256k1)
     signed_copy = ClaimDict.load_protobuf(signed.protobuf)
     self.assertEqual(signed_copy.validate_signature(claim_address_2, cert), True)
Exemplo n.º 15
0
 def test_validate_detached_named_ecdsa_signature_from_dict(self):
     cert = ClaimDict.generate_certificate(secp256k1_private_key,
                                           curve=SECP256k1)
     self.assertDictEqual(cert.claim_dict, secp256k1_cert)
     signed = ClaimDict.load_dict(example_010).sign(secp256k1_private_key,
                                                    claim_address_2,
                                                    claim_id_1,
                                                    curve=SECP256k1,
                                                    name='example',
                                                    force_detached=True)
     self.assertEqual(
         signed.claim_dict['publisherSignature']['detached_signature'],
         binascii.hexlify(signed.serialized).decode())
     signed_copy = ClaimDict.load_dict(signed.claim_dict)
     self.assertEqual(
         signed_copy.validate_signature(claim_address_2,
                                        cert,
                                        name='example'), True)
Exemplo n.º 16
0
    async def download_stream_from_uri(self, uri, exchange_rate_manager: 'ExchangeRateManager',
                                       file_name: typing.Optional[str] = None,
                                       timeout: typing.Optional[float] = None) -> typing.Optional[ManagedStream]:
        timeout = timeout or self.config.download_timeout
        parsed_uri = parse_lbry_uri(uri)
        if parsed_uri.is_channel:
            raise Exception("cannot download a channel claim, specify a /path")

        resolved = (await self.wallet.resolve(uri)).get(uri, {})
        resolved = resolved if 'value' in resolved else resolved.get('claim')

        if not resolved:
            raise ResolveError(
                "Failed to resolve stream at lbry://{}".format(uri.replace("lbry://", ""))
            )
        if 'error' in resolved:
            raise ResolveError(f"error resolving stream: {resolved['error']}")

        claim = ClaimDict.load_dict(resolved['value'])
        fee_amount, fee_address = None, None
        if claim.has_fee:
            fee_amount = round(exchange_rate_manager.convert_currency(
                    claim.source_fee.currency, "LBC", claim.source_fee.amount
                ), 5)
            fee_address = claim.source_fee.address.decode()
        outpoint = f"{resolved['txid']}:{resolved['nout']}"
        existing = self.get_filtered_streams(outpoint=outpoint)

        if not existing:
            existing.extend(self.get_filtered_streams(sd_hash=claim.source_hash.decode()))
            if existing and existing[0].claim_id != resolved['claim_id']:
                raise Exception(f"stream for {existing[0].claim_id} collides with existing "
                                f"download {resolved['claim_id']}")
            elif not existing:
                existing.extend(self.get_filtered_streams(claim_id=resolved['claim_id']))
            if existing and existing[0].sd_hash != claim.source_hash.decode():
                log.info("claim contains an update to a stream we have, downloading it")
                stream = await self.download_stream_from_claim(
                    self.node, resolved, file_name, timeout, fee_amount, fee_address, False
                )
                log.info("started new stream, deleting old one")
                await self.delete_stream(existing[0])
                return stream
            elif existing:
                log.info("already have matching stream for %s", uri)
                stream = existing[0]
                await self.start_stream(stream)
                return stream
        else:
            stream = existing[0]
            await self.start_stream(stream)
            return stream
        log.info("download stream from %s", uri)
        return await self.download_stream_from_claim(
                self.node, resolved, file_name, timeout, fee_amount, fee_address
        )
Exemplo n.º 17
0
 def test_fail_to_sign_with_no_claim_address(self):
     cert = ClaimDict.generate_certificate(secp256k1_private_key,
                                           curve=SECP256k1)
     self.assertDictEqual(cert.claim_dict, secp256k1_cert)
     self.assertRaises(Exception,
                       ClaimDict.load_dict(example_010).sign,
                       secp256k1_private_key,
                       None,
                       claim_id_1,
                       curve=SECP256k1)
Exemplo n.º 18
0
def get_mock_wallet(sd_hash, storage):
    claim = {
        "address": "bYFeMtSL7ARuG1iMpjFyrnTe4oJHSAVNXF",
        "amount": "0.1",
        "claim_id": "c49566d631226492317d06ad7fdbe1ed32925124",
        "claim_sequence": 1,
        "decoded_claim": True,
        "depth": 1057,
        "effective_amount": "0.1",
        "has_signature": False,
        "height": 514081,
        "hex": "",
        "name": "33rpm",
        "nout": 0,
        "permanent_url": "33rpm#c49566d631226492317d06ad7fdbe1ed32925124",
        "supports": [],
        "txid":
        "81ac52662af926fdf639d56920069e0f63449d4cde074c61717cb99ddde40e3c",
        "value": {
            "claimType": "streamType",
            "stream": {
                "metadata": {
                    "author": "",
                    "description": "",
                    "language": "en",
                    "license": "None",
                    "licenseUrl": "",
                    "nsfw": False,
                    "preview": "",
                    "thumbnail": "",
                    "title": "33rpm",
                    "version": "_0_1_0"
                },
                "source": {
                    "contentType": "image/png",
                    "source": sd_hash,
                    "sourceType": "lbry_sd_hash",
                    "version": "_0_0_1"
                },
                "version": "_0_0_1"
            },
            "version": "_0_0_1"
        }
    }
    claim_dict = ClaimDict.load_dict(claim['value'])
    claim['hex'] = binascii.hexlify(claim_dict.serialized).decode()

    async def mock_resolve(*args):
        await storage.save_claims([claim])
        return {claim['permanent_url']: claim}

    mock_wallet = mock.Mock(spec=LbryWalletManager)
    mock_wallet.resolve = mock_resolve
    return mock_wallet, claim['permanent_url']
Exemplo n.º 19
0
 async def craft_claim(self, name, amount_dewies, claim_dict, address):
     # FIXME: this is here mostly because publish has defensive code for situations that happens accidentally
     # However, it still happens... So, let's reproduce them.
     claim = ClaimDict.load_dict(claim_dict)
     address = address or (await self.account.receiving.get_addresses(limit=1, only_usable=True))[0]
     tx = await Transaction.claim(name, claim, amount_dewies, address, [self.account], self.account)
     await self.broadcast(tx)
     await self.ledger.wait(tx)
     await self.generate(1)
     await self.ledger.wait(tx)
     return tx
Exemplo n.º 20
0
 def test_fail_to_validate_fake_ecdsa_signature(self):
     signed = ClaimDict.load_dict(example_010).sign(secp256k1_private_key,
                                                    claim_address_1,
                                                    claim_id_1,
                                                    curve=SECP256k1,
                                                    name='example',
                                                    force_detached=True)
     signed_copy = ClaimDict.deserialize(signed.serialized)
     fake_key = get_signer(SECP256k1).generate().private_key.to_pem()
     fake_cert = ClaimDict.generate_certificate(fake_key, curve=SECP256k1)
     self.assertRaises(ecdsa.keys.BadSignatureError,
                       signed_copy.validate_signature, claim_address_2,
                       fake_cert, 'example')
Exemplo n.º 21
0
 def test_validate_detached_named_ecdsa_signature(self):
     cert = ClaimDict.generate_certificate(secp256k1_private_key,
                                           curve=SECP256k1)
     self.assertDictEqual(cert.claim_dict, secp256k1_cert)
     signed = ClaimDict.load_dict(example_010).sign(secp256k1_private_key,
                                                    claim_address_2,
                                                    claim_id_1,
                                                    curve=SECP256k1,
                                                    name='example',
                                                    force_detached=True)
     signed_copy = ClaimDict.deserialize(signed.serialized)
     self.assertEqual(
         signed_copy.validate_signature(claim_address_2,
                                        cert,
                                        name='example'), True)
Exemplo n.º 22
0
    async def test_new_signature_model_from_unserializable_claim(self):
        address1, address2 = await self.account.receiving.get_addresses(
            limit=2, only_usable=True)
        sendtxid1 = await self.blockchain.send_to_address(address1, 5)
        sendtxid2 = await self.blockchain.send_to_address(address2, 5)
        await self.blockchain.generate(1)
        await asyncio.wait([
            self.on_transaction_id(sendtxid1),
            self.on_transaction_id(sendtxid2)
        ])

        self.assertEqual(d2l(await self.account.get_balance()), '10.0')

        cert, key = generate_certificate()
        cert_tx = await Transaction.claim('@bar', cert, l2d('1.0'), address1,
                                          [self.account], self.account)
        original = ClaimDict.load_dict(example_claim_dict).serialized
        altered = original + b'\x00\x01\x02\x30\x50\x80\x99'  # pretend this extra trash is from some unknown protobuf

        # manually sign
        signer = get_signer(SECP256k1).load_pem(key)
        signature = signer.sign(
            b'foo',
            decode_address(address1),
            altered,
            binascii.unhexlify(cert_tx.outputs[0].claim_id),
        )
        detached_sig = Signature(
            NAMED_SECP256K1(signature,
                            binascii.unhexlify(cert_tx.outputs[0].claim_id),
                            altered))
        claim_tx = await Transaction.claim('foo', detached_sig, l2d('1.0'),
                                           address1, [self.account],
                                           self.account)

        await self.broadcast(cert_tx)
        await self.broadcast(claim_tx)
        await self.ledger.wait(claim_tx)
        await self.blockchain.generate(1)
        await self.ledger.wait(claim_tx)

        response = await self.ledger.resolve(0, 10, 'lbry://@bar/foo')
        self.assertIn('lbry://@bar/foo', response)
        self.assertIn('claim', response['lbry://@bar/foo'])
Exemplo n.º 23
0
 async def claim_name(self,
                      account,
                      name,
                      amount,
                      claim_dict,
                      certificate=None,
                      claim_address=None):
     claim = ClaimDict.load_dict(claim_dict)
     if not claim_address:
         claim_address = await account.receiving.get_or_create_usable_address(
         )
     if certificate:
         claim = claim.sign(
             certificate.private_key,
             claim_address,
             certificate.claim_id,
             curve=SECP256k1,
             name=name,
             force_detached=
             False  # TODO: delete it and make True default everywhere when its out
         )
     existing_claims = await account.get_claims(
         claim_name_type__any={
             'is_claim': 1,
             'is_update': 1
         },  # exclude is_supports
         claim_name=name)
     if len(existing_claims) == 0:
         tx = await Transaction.claim(name, claim, amount, claim_address,
                                      [account], account)
     elif len(existing_claims) == 1:
         tx = await Transaction.update(existing_claims[0], claim, amount,
                                       claim_address, [account], account)
     else:
         raise NameError(
             f"More than one other claim exists with the name '{name}'.")
     await account.ledger.broadcast(tx)
     await self.old_db.save_claims([
         self._old_get_temp_claim_info(tx, tx.outputs[0], claim_address,
                                       claim_dict, name,
                                       dewies_to_lbc(amount))
     ])
     # TODO: release reserved tx outputs in case anything fails by this point
     return tx
Exemplo n.º 24
0
def migrate_003_to_010(value):
    migrated_to_003 = LegacyMetadata(value)
    metadata = {"version": "_0_1_0"}
    for k in [
            "author", "description", "language", "license", "nsfw",
            "thumbnail", "title", "preview"
    ]:
        if k in migrated_to_003:
            metadata.update({k: migrated_to_003[k]})

    if 'license_url' in migrated_to_003:
        metadata['licenseUrl'] = migrated_to_003['license_url']

    if "fee" in migrated_to_003:
        fee = migrated_to_003["fee"]
        currency = list(fee.keys())[0]
        amount = fee[currency]['amount']
        address = fee[currency]['address']
        metadata.update(
            dict(
                fee={
                    "currency": currency,
                    "version": "_0_0_1",
                    "amount": amount,
                    "address": address
                }))
    source = {
        "source": migrated_to_003['sources']['lbry_sd_hash'],
        "contentType": migrated_to_003['content_type'],
        "sourceType": "lbry_sd_hash",
        "version": "_0_0_1"
    }

    migrated = {
        "version": "_0_0_1",
        "claimType": "streamType",
        "stream": {
            "version": "_0_0_1",
            "metadata": metadata,
            "source": source
        }
    }
    return ClaimDict.load_dict(migrated)
Exemplo n.º 25
0
    async def _download_stream_from_claim(self, node: 'Node', download_directory: str, claim_info: typing.Dict,
                                          file_name: typing.Optional[str] = None) -> typing.Optional[ManagedStream]:

        claim = ClaimDict.load_dict(claim_info['value'])
        downloader = StreamDownloader(self.loop, self.blob_manager, claim.source_hash.decode(), self.peer_timeout,
                                      self.peer_connect_timeout, download_directory, file_name, self.fixed_peers)
        try:
            downloader.download(node)
            await downloader.got_descriptor.wait()
            log.info("got descriptor %s for %s", claim.source_hash.decode(), claim_info['name'])
        except (asyncio.TimeoutError, asyncio.CancelledError):
            log.info("stream timeout")
            await downloader.stop()
            log.info("stopped stream")
            return
        if not await self.blob_manager.storage.stream_exists(downloader.sd_hash):
            await self.blob_manager.storage.store_stream(downloader.sd_blob, downloader.descriptor)
        if not await self.blob_manager.storage.file_exists(downloader.sd_hash):
            await self.blob_manager.storage.save_downloaded_file(
                downloader.descriptor.stream_hash, os.path.basename(downloader.output_path), download_directory,
                0.0
            )
        await self.blob_manager.storage.save_content_claim(
            downloader.descriptor.stream_hash, f"{claim_info['txid']}:{claim_info['nout']}"
        )

        stored_claim = StoredStreamClaim(
            downloader.descriptor.stream_hash, f"{claim_info['txid']}:{claim_info['nout']}", claim_info['claim_id'],
            claim_info['name'], claim_info['amount'], claim_info['height'], claim_info['hex'],
            claim.certificate_id, claim_info['address'], claim_info['claim_sequence'],
            claim_info.get('channel_name')
        )
        stream = ManagedStream(self.loop, self.blob_manager, downloader.descriptor, download_directory,
                               os.path.basename(downloader.output_path), downloader, ManagedStream.STATUS_RUNNING,
                               stored_claim)
        self.streams.add(stream)
        try:
            await stream.downloader.wrote_bytes_event.wait()
            self.wait_for_stream_finished(stream)
            return stream
        except asyncio.CancelledError:
            await downloader.stop()
Exemplo n.º 26
0
    def test_fail_to_validate_ecdsa_sig_for_altered_claim(self):
        cert = ClaimDict.generate_certificate(secp256k1_private_key,
                                              curve=SECP256k1)
        altered = ClaimDict.load_dict(example_010).sign(secp256k1_private_key,
                                                        claim_address_1,
                                                        claim_id_1,
                                                        curve=SECP256k1,
                                                        name='example',
                                                        force_detached=True)
        original_serialization = altered.serialized
        sd_hash = altered['stream']['source']['source']
        altered['stream']['source']['source'] = sd_hash[::-1]
        altered_serialization = altered.protobuf.SerializeToString()

        # keep signature, but replace serialization with the altered claim (check signature.py for slice sizes)
        altered_copy = ClaimDict.deserialize(original_serialization[:85] +
                                             altered_serialization)
        self.assertRaises(ecdsa.keys.BadSignatureError,
                          altered_copy.validate_signature, claim_address_1,
                          cert, 'example')
Exemplo n.º 27
0
    async def test_creating_updating_and_abandoning_claim_with_channel(self):

        await self.account.ensure_address_gap()

        address1, address2 = await self.account.receiving.get_addresses(
            limit=2, only_usable=True)
        sendtxid1 = await self.blockchain.send_to_address(address1, 5)
        sendtxid2 = await self.blockchain.send_to_address(address2, 5)
        await self.blockchain.generate(1)
        await asyncio.wait([
            self.on_transaction_id(sendtxid1),
            self.on_transaction_id(sendtxid2)
        ])

        self.assertEqual(d2l(await self.account.get_balance()), '10.0')

        cert, key = generate_certificate()
        cert_tx = await Transaction.claim('@bar', cert, l2d('1.0'), address1,
                                          [self.account], self.account)
        claim = ClaimDict.load_dict(example_claim_dict)
        claim = claim.sign(key,
                           address1,
                           cert_tx.outputs[0].claim_id,
                           name='foo')
        claim_tx = await Transaction.claim('foo', claim, l2d('1.0'), address1,
                                           [self.account], self.account)

        await self.broadcast(cert_tx)
        await self.broadcast(claim_tx)
        await asyncio.wait([  # mempool
            self.ledger.wait(claim_tx),
            self.ledger.wait(cert_tx)
        ])
        await self.blockchain.generate(1)
        await asyncio.wait([  # confirmed
            self.ledger.wait(claim_tx),
            self.ledger.wait(cert_tx)
        ])

        self.assertEqual(d2l(await self.account.get_balance()), '7.985786')
        self.assertEqual(
            d2l(await self.account.get_balance(include_claims=True)),
            '9.985786')

        response = await self.ledger.resolve(0, 10, 'lbry://@bar/foo')
        self.assertIn('lbry://@bar/foo', response)
        self.assertIn('claim', response['lbry://@bar/foo'])

        abandon_tx = await Transaction.abandon([claim_tx.outputs[0]],
                                               [self.account], self.account)
        await self.broadcast(abandon_tx)
        await self.ledger.wait(abandon_tx)
        await self.blockchain.generate(1)
        await self.ledger.wait(abandon_tx)

        response = await self.ledger.resolve(0, 10, 'lbry://@bar/foo')
        self.assertNotIn('claim', response['lbry://@bar/foo'])

        # checks for expected format in inexistent URIs
        response = await self.ledger.resolve(0, 10, 'lbry://404',
                                             'lbry://@404')
        self.assertEqual('URI lbry://404 cannot be resolved',
                         response['lbry://404']['error'])
        self.assertEqual('URI lbry://@404 cannot be resolved',
                         response['lbry://@404']['error'])
Exemplo n.º 28
0
 def test_fail_to_load_wrong_private_key_for_cert(self):
     cert_claim = ClaimDict.load_dict(secp256k1_cert)
     self.assertEqual(cert_claim.validate_private_key(nist256p_private_key, claim_id_1),
                      False)
Exemplo n.º 29
0
 def test_valid_private_key_for_cert(self):
     cert_claim = ClaimDict.load_dict(secp256k1_cert)
     self.assertEqual(cert_claim.validate_private_key(secp256k1_private_key, claim_id_1),
                      True)
Exemplo n.º 30
0
 def test_invalid_cert_curve(self):
     with self.assertRaises(Exception):
         ClaimDict.load_dict(malformed_secp256k1_cert)