Ejemplo n.º 1
0
 def get_channel_update(self, channel, amount, key=b'a'):
     self._set_channel_key(channel, key)
     return self._make_tx(
         Output.pay_update_claim_pubkey_hash(amount, channel.claim_name,
                                             channel.claim_id,
                                             channel.claim, b'abc'),
         Input.spend(channel))
Ejemplo n.º 2
0
    async def test_sign(self):
        account = self.ledger.account_class.from_dict(
            self.ledger, Wallet(), {
                "seed":
                    "carbon smart garage balance margin twelve chest sword toas"
                    "t envelope bottom stomach absent"
            }
        )

        await account.ensure_address_gap()
        address1, address2 = await account.receiving.get_addresses(limit=2)
        pubkey_hash1 = self.ledger.address_to_hash160(address1)
        pubkey_hash2 = self.ledger.address_to_hash160(address2)

        tx = Transaction() \
            .add_inputs([Input.spend(get_output(int(2*COIN), pubkey_hash1))]) \
            .add_outputs([Output.pay_pubkey_hash(int(1.9*COIN), pubkey_hash2)])

        await tx.sign([account])

        self.assertEqual(
            hexlify(tx.inputs[0].script.values['signature']),
            b'304402200dafa26ad7cf38c5a971c8a25ce7d85a076235f146126762296b1223c42ae21e022020ef9eeb8'
            b'398327891008c5c0be4357683f12cb22346691ff23914f457bf679601'
        )
Ejemplo n.º 3
0
 def get_stream_update(self, tx, amount):
     claim = Transaction(tx[0].serialize()).outputs[0]
     return self._make_tx(
         Output.pay_update_claim_pubkey_hash(
             amount, claim.claim_name, claim.claim_id, claim.claim, b'abc'
         ),
         Input.spend(claim)
     )
Ejemplo n.º 4
0
 def get_stream_update(self, tx, amount, channel=None):
     stream = Transaction(tx[0].raw).outputs[0]
     result = self._make_tx(
         Output.pay_update_claim_pubkey_hash(amount, stream.claim_name,
                                             stream.claim_id, stream.claim,
                                             b'abc'), Input.spend(stream))
     if channel:
         result[0].outputs[0].sign(channel)
         result[0]._reset()
     return result
Ejemplo n.º 5
0
    async def test_history_edge_cases(self):
        await self.blockchain.generate(300)
        await self.assertBalance(self.account, '0.0')
        address = await self.account.receiving.get_or_create_usable_address()
        # evil trick: mempool is unsorted on real life, but same order between python instances. reproduce it
        original_summary = self.conductor.spv_node.server.mempool.transaction_summaries

        async def random_summary(*args, **kwargs):
            summary = await original_summary(*args, **kwargs)
            if summary and len(summary) > 2:
                ordered = summary.copy()
                while summary == ordered:
                    random.shuffle(summary)
            return summary

        self.conductor.spv_node.server.mempool.transaction_summaries = random_summary
        # 10 unconfirmed txs, all from blockchain wallet
        sends = [
            self.blockchain.send_to_address(address, 10) for _ in range(10)
        ]
        # use batching to reduce issues with send_to_address on cli
        for batch in range(0, len(sends), 10):
            txids = await asyncio.gather(*sends[batch:batch + 10])
            await asyncio.wait(
                [self.on_transaction_id(txid) for txid in txids])
        remote_status = await self.ledger.network.subscribe_address(address)
        self.assertTrue(await
                        self.ledger.update_history(address, remote_status))
        # 20 unconfirmed txs, 10 from blockchain, 10 from local to local
        utxos = await self.account.get_utxos()
        txs = []
        for utxo in utxos:
            tx = await Transaction.create([Input.spend(utxo)], [],
                                          [self.account], self.account)
            await self.broadcast(tx)
            txs.append(tx)
        await asyncio.wait(
            [self.on_transaction_address(tx, address) for tx in txs],
            timeout=1)
        remote_status = await self.ledger.network.subscribe_address(address)
        self.assertTrue(await
                        self.ledger.update_history(address, remote_status))
        # server history grows unordered
        txid = await self.blockchain.send_to_address(address, 1)
        await self.on_transaction_id(txid)
        self.assertTrue(await
                        self.ledger.update_history(address, remote_status))
        self.assertEqual(
            21,
            len((await self.ledger.get_local_status_and_history(address))[1]))
        self.assertEqual(0, len(self.ledger._known_addresses_out_of_sync))
Ejemplo n.º 6
0
    async def test_sending_and_receiving(self):
        account1, account2 = self.account, self.wallet.generate_account(self.ledger)
        await self.ledger.subscribe_account(account2)

        await self.assertBalance(account1, '0.0')
        await self.assertBalance(account2, '0.0')

        addresses = await account1.receiving.get_addresses()
        txids = await asyncio.gather(*(
            self.blockchain.send_to_address(address, 1.1) for address in addresses[:5]
        ))
        await asyncio.wait([self.on_transaction_id(txid) for txid in txids])  # mempool
        await self.blockchain.generate(1)
        await asyncio.wait([self.on_transaction_id(txid) for txid in txids])  # confirmed
        await self.assertBalance(account1, '5.5')
        await self.assertBalance(account2, '0.0')

        address2 = await account2.receiving.get_or_create_usable_address()
        tx = await Transaction.create(
            [],
            [Output.pay_pubkey_hash(
                coins_to_satoshis('2.0'), self.ledger.address_to_hash160(address2)
            )],
            [account1], account1
        )
        await self.broadcast(tx)
        await self.ledger.wait(tx)  # mempool
        await self.blockchain.generate(1)
        await self.ledger.wait(tx)  # confirmed

        await self.assertBalance(account1, '3.499802')
        await self.assertBalance(account2, '2.0')

        utxos = await self.account.get_utxos()
        tx = await Transaction.create(
            [Input.spend(utxos[0])],
            [],
            [account1], account1
        )
        await self.broadcast(tx)
        await self.ledger.wait(tx)  # mempool
        await self.blockchain.generate(1)
        await self.ledger.wait(tx)  # confirmed

        tx = (await account1.get_transactions(include_is_my_input=True, include_is_my_output=True))[1]
        self.assertEqual(satoshis_to_coins(tx.inputs[0].amount), '1.1')
        self.assertEqual(satoshis_to_coins(tx.inputs[1].amount), '1.1')
        self.assertEqual(satoshis_to_coins(tx.outputs[0].amount), '2.0')
        self.assertEqual(tx.outputs[0].get_address(self.ledger), address2)
        self.assertTrue(tx.outputs[0].is_internal_transfer)
        self.assertTrue(tx.outputs[1].is_internal_transfer)
Ejemplo n.º 7
0
    async def test_get_utxo(self):
        address = yield self.account.receiving.get_or_create_usable_address()
        hash160 = self.ledger.address_to_hash160(address)

        tx = Transaction(is_verified=True)\
            .add_outputs([Output.pay_pubkey_hash(100, hash160)])
        await self.ledger.db.save_transaction_io('insert', tx, address,
                                                 hash160, f'{tx.id}:1:')

        utxos = await self.account.get_utxos()
        self.assertEqual(len(utxos), 1)

        tx = Transaction(is_verified=True)\
            .add_inputs([Input.spend(utxos[0])])
        await self.ledger.db.save_transaction_io('insert', tx, address,
                                                 hash160, f'{tx.id}:1:')
        self.assertEqual(await self.account.get_balance(include_claims=True),
                         0)

        utxos = await self.account.get_utxos()
        self.assertEqual(len(utxos), 0)
Ejemplo n.º 8
0
def get_input():
    return Input.spend(get_output())
Ejemplo n.º 9
0
 def get_abandon(self, tx):
     claim = Transaction(tx[0].raw).outputs[0]
     return self._make_tx(Output.pay_pubkey_hash(claim.amount, b'abc'),
                          Input.spend(claim))
Ejemplo n.º 10
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')

        channel = Claim()
        channel_txo = Output.pay_claim_name_pubkey_hash(
            l2d('1.0'), '@bar', channel,
            self.account.ledger.address_to_hash160(address1))
        channel_txo.generate_channel_private_key()
        channel_txo.script.generate()
        channel_tx = await Transaction.create([], [channel_txo],
                                              [self.account], self.account)

        stream = Claim()
        stream.stream.source.media_type = "video/mp4"
        stream_txo = Output.pay_claim_name_pubkey_hash(
            l2d('1.0'), 'foo', stream,
            self.account.ledger.address_to_hash160(address1))
        stream_tx = await Transaction.create([], [stream_txo], [self.account],
                                             self.account)
        stream_txo.sign(channel_txo)
        await stream_tx.sign([self.account])

        await self.broadcast(channel_tx)
        await self.broadcast(stream_tx)
        await asyncio.wait([  # mempool
            self.ledger.wait(channel_tx),
            self.ledger.wait(stream_tx)
        ])
        await self.blockchain.generate(1)
        await asyncio.wait([  # confirmed
            self.ledger.wait(channel_tx),
            self.ledger.wait(stream_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([], ['lbry://@bar/foo'])
        self.assertEqual(response['lbry://@bar/foo'].claim.claim_type,
                         'stream')

        abandon_tx = await Transaction.create(
            [Input.spend(stream_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([], ['lbry://@bar/foo'])
        self.assertIn('error', response['lbry://@bar/foo'])

        # checks for expected format in inexistent URIs
        response = await self.ledger.resolve([], ['lbry://404', 'lbry://@404'])
        self.assertEqual('lbry://404 did not resolve to a claim',
                         response['lbry://404']['error'])
        self.assertEqual('lbry://@404 did not resolve to a claim',
                         response['lbry://@404']['error'])
Ejemplo n.º 11
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)
        notifications = asyncio.create_task(asyncio.wait(
            [asyncio.ensure_future(self.on_address_update(address1)),
             asyncio.ensure_future(self.on_address_update(address2))]
        ))
        await self.send_to_address_and_wait(address1, 5)
        await self.send_to_address_and_wait(address2, 5, 1)
        await notifications

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

        channel = Claim()
        channel_txo = Output.pay_claim_name_pubkey_hash(
            l2d('1.0'), '@bar', channel, self.account.ledger.address_to_hash160(address1)
        )
        channel_txo.set_channel_private_key(
            await self.account.generate_channel_private_key()
        )
        channel_txo.script.generate()
        channel_tx = await Transaction.create([], [channel_txo], [self.account], self.account)

        stream = Claim()
        stream.stream.source.media_type = "video/mp4"
        stream_txo = Output.pay_claim_name_pubkey_hash(
            l2d('1.0'), 'foo', stream, self.account.ledger.address_to_hash160(address1)
        )
        stream_tx = await Transaction.create([], [stream_txo], [self.account], self.account)
        stream_txo.sign(channel_txo)
        await stream_tx.sign([self.account])

        notifications = asyncio.create_task(asyncio.wait(
            [asyncio.ensure_future(self.ledger.wait(channel_tx)), asyncio.ensure_future(self.ledger.wait(stream_tx))]
        ))

        await self.broadcast(channel_tx)
        await self.broadcast(stream_tx)
        await notifications
        notifications = asyncio.create_task(asyncio.wait(
            [asyncio.ensure_future(self.ledger.wait(channel_tx)), asyncio.ensure_future(self.ledger.wait(stream_tx))]
        ))
        await self.generate(1)
        await notifications
        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([], ['lbry://@bar/foo'])
        self.assertEqual(response['lbry://@bar/foo'].claim.claim_type, 'stream')

        abandon_tx = await Transaction.create([Input.spend(stream_tx.outputs[0])], [], [self.account], self.account)
        notify = asyncio.create_task(self.ledger.wait(abandon_tx))
        await self.broadcast(abandon_tx)
        await notify
        notify = asyncio.create_task(self.ledger.wait(abandon_tx))
        await self.generate(1)
        await notify

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

        # checks for expected format in inexistent URIs
        response = await self.ledger.resolve([], ['lbry://404', 'lbry://@404', 'lbry://@404/404'])
        self.assertEqual('Could not find claim at "lbry://404".', response['lbry://404']['error']['text'])
        self.assertEqual('Could not find channel in "lbry://@404".', response['lbry://@404']['error']['text'])
        self.assertEqual('Could not find channel in "lbry://@404/404".', response['lbry://@404/404']['error']['text'])