Example #1
0
    def submit_send_tx(self, tx: TransferTransaction) -> bool:
        if tx is None:
            raise ValueError("The transaction was empty")

        if tx.subtype == qrl_pb2.Transaction.LATTICE:
            self._p2pfactory.broadcast_lt(tx)
        elif tx.subtype in (qrl_pb2.Transaction.TRANSFER,
                            qrl_pb2.Transaction.MESSAGE,
                            qrl_pb2.Transaction.TOKEN,
                            qrl_pb2.Transaction.TRANSFERTOKEN):
            tx.validate_or_raise()

            block_number = self._buffered_chain.height + 1
            tx_state = self._buffered_chain.get_stxn_state(block_number, tx.txfrom)

            if not tx.validate_extended(tx_state=tx_state,
                                        transaction_pool=self._buffered_chain.tx_pool.transaction_pool):
                raise ValueError("The transaction failed validatation (blockchain state)")

            self._buffered_chain.tx_pool.add_tx_to_pool(tx)
            self._buffered_chain.wallet.save_wallet()
            # FIXME: Optimization Required
            subtype = 'TX'
            if tx.subtype == qrl_pb2.Transaction.MESSAGE:
                subtype = 'MT'
            elif tx.subtype == qrl_pb2.Transaction.TOKEN:
                subtype = 'TK'
            elif tx.subtype == qrl_pb2.Transaction.TRANSFERTOKEN:
                subtype = 'TT'
            self._p2pfactory.broadcast_tx(tx, subtype=subtype)

        return True
Example #2
0
 def test_create_negative_fee(self):
     with self.assertRaises(ValueError):
         TransferTransaction.create(addr_from=self.alice.address,
                                    addrs_to=[self.bob.address],
                                    amounts=[-100],
                                    fee=-1,
                                    xmss_pk=self.alice.pk)
Example #3
0
 def test_create_negative_amount(self):
     with self.assertRaises(ValueError):
         TransferTransaction.create(
             addr_from=self.alice.get_address().encode(),
             addr_to=self.bob.get_address().encode(),
             amount=-100,
             fee=1,
             xmss_pk=self.alice.pk(),
             xmss_ots_index=self.alice.get_index())
Example #4
0
def transfer(destinations, fee, mixin, unlock_time):
    if len(destinations) > config.dev.transaction_multi_output_limit:
        raise Exception('Payment Failed: Amount exceeds the allowed limit')

    addrs_to = []
    amounts = []

    for tx in destinations:
        addrs_to.append(bytes(hstr2bin(tx['address'][1:])))  # Skipping 'Q'
        amounts.append(tx['amount'])

    stub = get_public_stub()

    xmss = get_unused_payment_xmss(stub)
    if not xmss:
        raise Exception('Payment Failed: No Unused Payment XMSS found')

    tx = TransferTransaction.create(addrs_to=addrs_to,
                                    amounts=amounts,
                                    fee=fee,
                                    xmss_pk=xmss.pk,
                                    master_addr=payment_slaves[0])

    tx.sign(xmss)

    response = stub.PushTransaction(request=qrl_pb2.PushTransactionReq(
        transaction_signed=tx.pbdata))

    if response.error_code != 3:
        raise Exception('Transaction Submission Failed, Response Code: %s',
                        response.error_code)

    response = {'tx_hash': bin2hstr(tx.txhash)}

    return response
Example #5
0
 def test_create(self):
     # Alice sending coins to Bob
     tx = TransferTransaction.create(addrs_to=[self.bob.address],
                                     amounts=[100],
                                     fee=1,
                                     xmss_pk=self.alice.pk)
     self.assertTrue(tx)
Example #6
0
def transfer(destinations, fee, mixin, unlock_time):
    if len(destinations) > config.dev.transaction_multi_output_limit:
        return None

    addrs_to = []
    amounts = []

    for tx in destinations:
        addrs_to.append(bytes(hstr2bin(tx['address'][1:])))  # Skipping 'Q'
        amounts.append(tx['amount'])

    stub = get_public_stub()

    xmss = get_unused_payment_xmss(stub)
    if not xmss:
        return None

    tx = TransferTransaction.create(addr_from=payment_slaves[0],
                                    addrs_to=addrs_to,
                                    amounts=amounts,
                                    fee=fee,
                                    xmss_pk=xmss.pk)

    tx.sign(xmss)

    response = stub.PushTransaction(request=qrl_pb2.PushTransactionReq(
        transaction_signed=tx.pbdata))

    if response.error_code != 3:
        return None

    response = {'tx_hash': bin2hstr(tx.txhash)}

    return response
Example #7
0
    def test_prepare_address_list(self):
        with set_qrl_dir('no_data'):
            with State() as state:
                block = Block.create(block_number=10,
                                     prev_block_headerhash=b'',
                                     prev_block_timestamp=10,
                                     transactions=[],
                                     miner_address=b'addr1')
                # Test Case: without any transactions of block
                self.assertEqual(state.prepare_address_list(block),
                                 {config.dev.coinbase_address, b'addr1'})

                alice_xmss = get_alice_xmss()
                block = Block.create(block_number=10,
                                     prev_block_headerhash=b'',
                                     prev_block_timestamp=10,
                                     transactions=[
                                         TransferTransaction.create(
                                             addrs_to=[b'addr2', b'addr3'],
                                             amounts=[100, 100],
                                             fee=0,
                                             xmss_pk=alice_xmss.pk)
                                     ],
                                     miner_address=b'addr1')

                # Test Case, with one Transaction
                self.assertEqual(
                    state.prepare_address_list(block), {
                        config.dev.coinbase_address, b'addr1', b'addr2',
                        b'addr3', alice_xmss.address
                    })
Example #8
0
    def test_to_json(self):
        tx = TransferTransaction.create(addrs_to=[self.bob.address],
                                        amounts=[100],
                                        fee=1,
                                        xmss_pk=self.alice.pk)
        txjson = tx.to_json()

        self.assertEqual(json.loads(test_json_Simple), json.loads(txjson))
Example #9
0
def create_tx(addrs_to, amounts, signing_xmss, nonce):
    tx = TransferTransaction.create(addrs_to=addrs_to,
                                    amounts=amounts,
                                    fee=0,
                                    xmss_pk=signing_xmss.pk)
    tx.sign(signing_xmss)
    tx._data.nonce = nonce
    return tx
Example #10
0
 def test_create(self):
     # Alice sending coins to Bob
     tx = TransferTransaction.create(
         addr_from=self.alice.get_address().encode(),
         addr_to=self.bob.get_address().encode(),
         amount=100,
         fee=1,
         xmss_pk=self.alice.pk(),
         xmss_ots_index=self.alice.get_index())
     self.assertTrue(tx)
Example #11
0
    def test_to_json(self):
        tx = TransferTransaction.create(
            addr_from=self.alice.get_address().encode(),
            addr_to=self.bob.get_address().encode(),
            amount=100,
            fee=1,
            xmss_pk=self.alice.pk(),
            xmss_ots_index=self.alice.get_index())
        txjson = tx.to_json()

        self.assertEqual(json.loads(test_json_Simple), json.loads(txjson))
Example #12
0
    def create_send_tx(self, addr_from: bytes, addrs_to: list, amounts: list,
                       fee: int, xmss_pk: bytes) -> TransferTransaction:
        balance = self.db_state.balance(addr_from)
        if sum(amounts) + fee > balance:
            raise RuntimeError("Not enough funds in the source address")

        return TransferTransaction.create(addr_from=addr_from,
                                          addrs_to=addrs_to,
                                          amounts=amounts,
                                          fee=fee,
                                          xmss_pk=xmss_pk)
Example #13
0
    def test_validate_tx(self):
        # If we change amount, fee, addr_from, addr_to, (maybe include xmss stuff) txhash should change.
        tx = TransferTransaction.create(addrs_to=[self.bob.address],
                                        amounts=[100],
                                        fee=1,
                                        xmss_pk=self.alice.pk)

        # We must sign the tx before validation will work.
        tx.sign(self.alice)

        # We have not touched the tx: validation should pass.
        self.assertTrue(tx.validate_or_raise())
Example #14
0
    def create_send_tx(self, addr_from: bytes, addr_to: bytes, amount: int,
                       fee: int, xmss_pk: bytes,
                       xmss_ots_index: int) -> TransferTransaction:
        balance = self.db_state.balance(addr_from)
        if amount + fee > balance:
            raise RuntimeError("Not enough funds in the source address")

        return TransferTransaction.create(addr_from=addr_from,
                                          addr_to=addr_to,
                                          amount=amount,
                                          fee=fee,
                                          xmss_pk=xmss_pk,
                                          xmss_ots_index=xmss_ots_index)
Example #15
0
    def test_update_last_tx(self):
        with set_qrl_dir('no_data'):
            with State() as state:
                alice_xmss = get_alice_xmss()
                # Test Case: When there is no last txns
                self.assertEqual(state.get_last_txs(), [])

                block = Block()
                tx1 = TransferTransaction.create(addrs_to=[b'q1', b'q2'],
                                                 amounts=[1, 2],
                                                 fee=0,
                                                 xmss_pk=alice_xmss.pk)
                block._data.transactions.extend([tx1.pbdata])
                state.update_last_tx(block, None)
                last_txns = state.get_last_txs()

                # Test Case: When there is only 1 last txns
                self.assertEqual(len(last_txns), 1)
                self.assertEqual(last_txns[0].to_json(), tx1.to_json())

                block = Block()
                tx2 = TransferTransaction.create(addrs_to=[b'q2', b'q3'],
                                                 amounts=[1, 2],
                                                 fee=0,
                                                 xmss_pk=alice_xmss.pk)

                tx3 = TransferTransaction.create(addrs_to=[b'q4', b'q5'],
                                                 amounts=[1, 2],
                                                 fee=0,
                                                 xmss_pk=alice_xmss.pk)
                block._data.transactions.extend([tx2.pbdata, tx3.pbdata])
                state.update_last_tx(block, None)
                last_txns = state.get_last_txs()

                # Test Case: When there are 3 last txns
                self.assertEqual(len(last_txns), 3)
                self.assertEqual(last_txns[0].to_json(), tx3.to_json())
                self.assertEqual(last_txns[1].to_json(), tx2.to_json())
                self.assertEqual(last_txns[2].to_json(), tx1.to_json())
Example #16
0
    def create_send_tx(self, addrs_to: list, amounts: list, fee: int,
                       xmss_pk: bytes,
                       master_addr: bytes) -> TransferTransaction:
        addr_from = self.get_addr_from(xmss_pk, master_addr)
        balance = self.db_state.balance(addr_from)
        if sum(amounts) + fee > balance:
            raise ValueError("Not enough funds in the source address")

        return TransferTransaction.create(addrs_to=addrs_to,
                                          amounts=amounts,
                                          fee=fee,
                                          xmss_pk=xmss_pk,
                                          master_addr=master_addr)
Example #17
0
    def test_update_tx_metadata(self):
        with set_qrl_dir('no_data'):
            with State() as state:
                alice_xmss = get_alice_xmss()
                tx = TransferTransaction.create(addrs_to=[b'q1', b'q2'],
                                                amounts=[1, 2],
                                                fee=0,
                                                xmss_pk=alice_xmss.pk)
                block_number = 5
                state.put_tx_metadata(tx, block_number, 10000, None)

                tx_metadata = state.get_tx_metadata(tx.txhash)
                self.assertEqual(tx_metadata[0].to_json(), tx.to_json())
                self.assertEqual(tx_metadata[1], block_number)
Example #18
0
    def test_validate_tx(self):
        # If we change amount, fee, txfrom, txto, (maybe include xmss stuff) txhash should change.
        tx = TransferTransaction.create(
            addr_from=self.alice.get_address().encode(),
            addr_to=self.bob.get_address().encode(),
            amount=100,
            fee=1,
            xmss_pk=self.alice.pk(),
            xmss_ots_index=self.alice.get_index())

        # We must sign the tx before validation will work.
        tx.sign(self.alice)

        # We have not touched the tx: validation should pass.
        self.assertTrue(tx.validate_or_raise())
Example #19
0
File: qrlnode.py Project: fanff/QRL
    def create_send_tx(self,
                       addr_from: bytes,
                       addr_to: bytes,
                       amount: int,
                       fee: int,
                       xmss_pk: bytes,
                       xmss_ots_index: int) -> TransferTransaction:
        balance = self.db_state.balance(addr_from)
        if amount + fee > balance:
            raise RuntimeError("Not enough funds in the source address")

        return TransferTransaction.create(addr_from=addr_from,
                                          addr_to=addr_to,
                                          amount=amount,
                                          fee=fee,
                                          xmss_pk=xmss_pk,
                                          xmss_ots_index=xmss_ots_index)
Example #20
0
    def create_unsigned_tx(self, transaction):
        if transaction.type == qrl_pb2.Transaction.TRANSFER:
            return TransferTransaction.create(transaction.addr_from,
                                              transaction.Transfer.addr_to,
                                              transaction.Transfer.amount,
                                              transaction.Transfer.fee,
                                              transaction.xmss_pk,
                                              transaction.xmss_ots_index)

        elif transaction.type == qrl_pb2.Transaction.LATTICE:
            return LatticePublicKey.create(transaction.addr_from,
                                           transaction.LatticePublicKey.kyber_pk,
                                           transaction.LatticePublicKey.tesla_pk,
                                           transaction.xmss_pk,
                                           transaction.xmss_ots_index)

        elif transaction.type == qrl_pb2.Transaction.MESSAGE:
            return MessageTransaction.create(transaction.addr_from,
                                             transaction.Message.message_hash,
                                             transaction.Message.fee,
                                             transaction.xmss_pk,
                                             transaction.xmss_ots_index)

        elif transaction.type == qrl_pb2.Transaction.TOKEN:
            return TokenTransaction.create(transaction.addr_from,
                                           transaction.Token.symbol,
                                           transaction.Token.name,
                                           transaction.Token.owner,
                                           transaction.Token.decimals,
                                           transaction.Token.initial_balances,
                                           transaction.Token.fee,
                                           transaction.xmss_pk,
                                           transaction.xmss_ots_index)

        elif transaction.type == qrl_pb2.Transaction.TRANSFERTOKEN:
            return TransferTokenTransaction.create(transaction.addr_from,
                                                   transaction.TransferToken.token_txhash,
                                                   transaction.TransferToken.addr_to,
                                                   transaction.TransferToken.amount,
                                                   transaction.TransferToken.fee,
                                                   transaction.xmss_pk,
                                                   transaction.xmss_ots_index)

        else:
            return None
Example #21
0
    def broadcast_tx(self, tx: TransferTransaction):
        logger.info('<<<Transmitting TX: %s', tx.txhash)

        if tx.subtype == qrl_pb2.Transaction.MESSAGE:
            legacy_type = qrllegacy_pb2.LegacyMessage.MT
        elif tx.subtype == qrl_pb2.Transaction.TRANSFER:
            legacy_type = qrllegacy_pb2.LegacyMessage.TX
        elif tx.subtype == qrl_pb2.Transaction.TOKEN:
            legacy_type = qrllegacy_pb2.LegacyMessage.TK
        elif tx.subtype == qrl_pb2.Transaction.TRANSFERTOKEN:
            legacy_type = qrllegacy_pb2.LegacyMessage.TT
        elif tx.subtype == qrl_pb2.Transaction.LATTICE:
            legacy_type = qrllegacy_pb2.LegacyMessage.LT
        elif tx.subtype == qrl_pb2.Transaction.SLAVE:
            legacy_type = qrllegacy_pb2.LegacyMessage.SL
        else:
            raise ValueError('Invalid Transaction Type')
        self.register_and_broadcast(legacy_type, tx.get_message_hash(), tx.pbdata)
Example #22
0
    def broadcast_tx(self, tx: TransferTransaction):
        logger.info('<<<Transmitting TX: %s', bin2hstr(tx.txhash))

        if isinstance(tx, MessageTransaction):
            legacy_type = qrllegacy_pb2.LegacyMessage.MT
        elif isinstance(tx, TransferTransaction):
            legacy_type = qrllegacy_pb2.LegacyMessage.TX
        elif isinstance(tx, TokenTransaction):
            legacy_type = qrllegacy_pb2.LegacyMessage.TK
        elif isinstance(tx, TransferTokenTransaction):
            legacy_type = qrllegacy_pb2.LegacyMessage.TT
        elif isinstance(tx, LatticePublicKey):
            legacy_type = qrllegacy_pb2.LegacyMessage.LT
        elif isinstance(tx, SlaveTransaction):
            legacy_type = qrllegacy_pb2.LegacyMessage.SL
        else:
            raise ValueError('Invalid Transaction Type')
        self.register_and_broadcast(legacy_type, tx.get_message_hash(), tx.pbdata)
Example #23
0
    def test_notification(self):
        source = Mock()
        source.factory = Mock()
        source.factory.master_mr = Mock()
        source.factory.master_mr.isRequested = Mock()
        source.factory.add_unprocessed_txn = Mock()

        channel = Observable(source)

        self.tx_manager = P2PTxManagement()
        self.tx_manager.new_channel(channel)

        tx = TransferTransaction.create([], [0], 10, xmss_pk=bytes(40))

        event = qrllegacy_pb2.LegacyMessage(func_name=qrllegacy_pb2.LegacyMessage.TX,
                                            txData=tx.pbdata)

        channel.notify(event, force_delivery=True)
        source.factory.master_mr.isRequested.assert_called()
        source.factory.add_unprocessed_txn.assert_called()
Example #24
0
    def test_rollback_tx_metadata(self):
        with set_qrl_dir('no_data'):
            with State() as state:
                alice_xmss = get_alice_xmss()

                tx1 = TransferTransaction.create(addrs_to=[b'q1', b'q2'],
                                                 amounts=[1, 2],
                                                 fee=0,
                                                 xmss_pk=alice_xmss.pk)

                block = Block.create(block_number=5,
                                     prevblock_headerhash=b'',
                                     transactions=[tx1],
                                     miner_address=b'')

                state.update_tx_metadata(block=block, batch=None)

                tx_metadata = state.get_tx_metadata(tx1.txhash)

                self.assertEqual(tx_metadata[0].to_json(), tx1.to_json())
                state.rollback_tx_metadata(block, None)
                self.assertIsNone(state.get_tx_metadata(tx1.txhash))
Example #25
0
    def test_remove_last_tx(self):
        with set_qrl_dir('no_data'):
            with State() as state:
                # Test Case: When there is no last txns
                self.assertEqual(state.get_last_txs(), [])

                alice_xmss = get_alice_xmss()

                block = Block()
                tx1 = TransferTransaction.create(addrs_to=[b'q1', b'q2'],
                                                 amounts=[1, 2],
                                                 fee=0,
                                                 xmss_pk=alice_xmss.pk)
                block._data.transactions.extend([tx1.pbdata])
                state.update_last_tx(block, None)
                last_txns = state.get_last_txs()

                self.assertEqual(last_txns[0].to_json(), tx1.to_json())

                state.remove_last_tx(block, None)
                last_txns = state.get_last_txs()
                self.assertEqual(last_txns, [])
Example #26
0
    def test_getLatestData(self):
        blocks = []
        txs = []
        for i in range(1, 4):
            for j in range(1, 3):
                txs.append(
                    TransferTransaction.create(addr_from=qrladdress('source'),
                                               addr_to=qrladdress('dest'),
                                               amount=i * 100 + j,
                                               fee=j,
                                               xmss_pk=get_alice_xmss().pk(),
                                               xmss_ots_index=i))

            blocks.append(
                Block.create(staking_address=qrladdress('staking_addr'),
                             block_number=i,
                             reveal_hash=sha256(b'reveal'),
                             prevblock_headerhash=sha256(b'reveal'),
                             transactions=txs,
                             duplicate_transactions=OrderedDict(),
                             vote=VoteMetadata(),
                             signing_xmss=get_alice_xmss(),
                             nonce=i))

        txpool = []
        for j in range(10, 15):
            txpool.append(
                TransferTransaction.create(addr_from=qrladdress('source'),
                                           addr_to=qrladdress('dest'),
                                           amount=1000 + j,
                                           fee=j,
                                           xmss_pk=get_alice_xmss().pk(),
                                           xmss_ots_index=j))

        db_state = Mock(spec=State)

        p2p_factory = Mock(spec=P2PFactory)
        buffered_chain = Mock(spec=BufferedChain)
        buffered_chain.tx_pool = Mock()
        buffered_chain.tx_pool.transaction_pool = txpool

        buffered_chain.get_block = Mock()
        buffered_chain.get_block.side_effect = blocks
        buffered_chain.height = len(blocks)

        buffered_chain._chain = Mock()
        buffered_chain._chain.blockchain = blocks

        qrlnode = QRLNode(db_state)
        qrlnode.set_p2pfactory(p2p_factory)
        qrlnode.set_chain(buffered_chain)

        service = PublicAPIService(qrlnode)
        context = Mock(spec=ServicerContext)

        request = qrl_pb2.GetLatestDataReq(filter=qrl_pb2.GetLatestDataReq.ALL,
                                           offset=1,
                                           quantity=3)

        response = service.GetLatestData(request=request, context=context)

        context.set_code.assert_not_called()
        context.set_details.assert_not_called()

        # Verify blockheaders
        self.assertEqual(2, len(response.blockheaders))
        self.assertEqual(1, response.blockheaders[0].header.block_number)
        self.assertEqual(2, response.blockheaders[1].header.block_number)

        # Verify transactions
        self.assertEqual(3, len(response.transactions))
        self.assertEqual(1, response.transactions[0].transfer.fee)
        self.assertEqual(2, response.transactions[1].transfer.fee)
        self.assertEqual(1, response.transactions[2].transfer.fee)

        # 302 should have been skipped
        self.assertEqual(301, response.transactions[0].transfer.amount)
        self.assertEqual(202, response.transactions[1].transfer.amount)
        self.assertEqual(201, response.transactions[2].transfer.amount)

        # Verify transactions_unconfirmed
        self.assertEqual(3, len(response.transactions_unconfirmed))
        self.assertEqual(1013,
                         response.transactions_unconfirmed[0].transfer.amount)
        self.assertEqual(1012,
                         response.transactions_unconfirmed[1].transfer.amount)
        self.assertEqual(1011,
                         response.transactions_unconfirmed[2].transfer.amount)
Example #27
0
    def test_add_4(self):
        destroy_state()
        with State() as state:
            with set_wallet_dir("test_wallet"):
                chain = Chain(state)
                buffered_chain = BufferedChain(chain)

                alice_xmss = get_alice_xmss()
                slave_xmss = XMSS(alice_xmss.height, alice_xmss.get_seed())
                random_xmss1 = get_random_xmss()
                random_xmss2 = get_random_xmss()
                staking_address = bytes(alice_xmss.get_address().encode())

                # FIXME: Replace this with a call to create a hash_chain
                h0 = sha256(b'hashchain_seed')
                h1 = sha256(h0)
                h2 = sha256(h1)
                h3 = sha256(h2)
                h4 = sha256(h3)

                with mocked_genesis() as custom_genesis:
                    custom_genesis.genesis_balance.extend([
                        qrl_pb2.GenesisBalance(
                            address=alice_xmss.get_address(),
                            balance=700000000000000)
                    ])

                    res = buffered_chain.add_block(block=GenesisBlock())
                    self.assertTrue(res)
                    stake_transaction = StakeTransaction.create(
                        activation_blocknumber=1,
                        xmss=alice_xmss,
                        slavePK=slave_xmss.pk(),
                        hashchain_terminator=h4)
                    stake_transaction._data.nonce = 1  # FIXME: The test needs private access.. This is an API issue
                    stake_transaction.sign(alice_xmss)

                    vote = Vote.create(
                        addr_from=alice_xmss.get_address().encode(),
                        blocknumber=0,
                        headerhash=GenesisBlock().headerhash,
                        xmss=slave_xmss)
                    vote.sign(slave_xmss)
                    buffered_chain.add_vote(vote)
                    vote_metadata = buffered_chain.get_consensus(0)

                    chain.pstate.stake_validators_tracker.add_sv(
                        balance=700000000000000,
                        stake_txn=stake_transaction,
                        blocknumber=1)

                    sv = chain.pstate.stake_validators_tracker.sv_dict[
                        staking_address]
                    self.assertEqual(0, sv.nonce)

                    # Token Transaction to create a token for test
                    token_transaction = get_token_transaction(
                        random_xmss1, random_xmss2)
                    token_transaction._data.nonce = 1
                    token_transaction.sign(random_xmss1)

                    # Transfer Token Transaction
                    transfer_token1 = TransferTokenTransaction.create(
                        addr_from=random_xmss1.get_address().encode(),
                        token_txhash=token_transaction.txhash,
                        addr_to=alice_xmss.get_address().encode(),
                        amount=100000000,
                        fee=1,
                        xmss_pk=random_xmss1.pk(),
                        xmss_ots_index=random_xmss1.get_index())
                    transfer_token1._data.nonce = 2
                    transfer_token1.sign(random_xmss1)

                    transfer_token2 = TransferTokenTransaction.create(
                        addr_from=random_xmss2.get_address().encode(),
                        token_txhash=token_transaction.txhash,
                        addr_to=alice_xmss.get_address().encode(),
                        amount=200000000,
                        fee=1,
                        xmss_pk=random_xmss2.pk(),
                        xmss_ots_index=random_xmss2.get_index())
                    transfer_token2._data.nonce = 1
                    transfer_token2.sign(random_xmss2)

                    # Transfer Coin Transaction
                    transfer_transaction = TransferTransaction.create(
                        addr_from=random_xmss1.get_address().encode(),
                        addr_to=random_xmss2.get_address().encode(),
                        amount=10,
                        fee=1,
                        xmss_pk=random_xmss1.pk(),
                        xmss_ots_index=random_xmss1.get_index())
                    transfer_transaction._data.nonce = 3
                    transfer_transaction.sign(random_xmss1)

                    tmp_block1 = Block.create(
                        staking_address=staking_address,
                        block_number=1,
                        reveal_hash=h3,
                        prevblock_headerhash=GenesisBlock().headerhash,
                        transactions=[stake_transaction, token_transaction],
                        duplicate_transactions=OrderedDict(),
                        vote=vote_metadata,
                        signing_xmss=slave_xmss,
                        nonce=1)

                    res = buffered_chain.add_block(block=tmp_block1)
                    self.assertTrue(res)

                    # Need to move forward the time to align with block times
                    with mock.patch('qrl.core.ntp.getTime') as time_mock:
                        time_mock.return_value = tmp_block1.timestamp + config.dev.minimum_minting_delay

                        vote = Vote.create(
                            addr_from=alice_xmss.get_address().encode(),
                            blocknumber=1,
                            headerhash=tmp_block1.headerhash,
                            xmss=slave_xmss)
                        vote.sign(slave_xmss)
                        buffered_chain.add_vote(vote)
                        vote_metadata = buffered_chain.get_consensus(1)

                        tmp_block2 = Block.create(
                            staking_address=staking_address,
                            block_number=2,
                            reveal_hash=h2,
                            prevblock_headerhash=tmp_block1.headerhash,
                            transactions=[
                                transfer_token1, transfer_token2,
                                transfer_transaction
                            ],
                            duplicate_transactions=OrderedDict(),
                            vote=vote_metadata,
                            signing_xmss=slave_xmss,
                            nonce=2)

                    res = buffered_chain.add_block(block=tmp_block2)
                    self.assertTrue(res)

                    # Need to move forward the time to align with block times
                    with mock.patch('qrl.core.ntp.getTime') as time_mock:
                        time_mock.return_value = tmp_block2.timestamp + config.dev.minimum_minting_delay

                        vote = Vote.create(
                            addr_from=alice_xmss.get_address().encode(),
                            blocknumber=2,
                            headerhash=tmp_block2.headerhash,
                            xmss=slave_xmss)
                        vote.sign(slave_xmss)
                        buffered_chain.add_vote(vote)
                        vote_metadata = buffered_chain.get_consensus(2)

                        tmp_block3 = Block.create(
                            staking_address=staking_address,
                            block_number=3,
                            reveal_hash=h1,
                            prevblock_headerhash=tmp_block2.headerhash,
                            transactions=[],
                            duplicate_transactions=OrderedDict(),
                            vote=vote_metadata,
                            signing_xmss=slave_xmss,
                            nonce=3)

                    res = buffered_chain.add_block(block=tmp_block3)
                    self.assertTrue(res)

                    chain = buffered_chain._chain
                    random_xmss1_state = chain.pstate._get_address_state(
                        random_xmss1.get_address().encode())
                    random_xmss2_state = chain.pstate._get_address_state(
                        random_xmss2.get_address().encode())

                    self.assertEqual(
                        random_xmss1_state.tokens[bin2hstr(
                            token_transaction.txhash).encode()], 400000000)
                    self.assertEqual(
                        random_xmss2_state.tokens[bin2hstr(
                            token_transaction.txhash).encode()], 200000000)

                    # Need to move forward the time to align with block times
                    with mock.patch('qrl.core.ntp.getTime') as time_mock:
                        time_mock.return_value = tmp_block3.timestamp + config.dev.minimum_minting_delay

                        vote = Vote.create(
                            addr_from=alice_xmss.get_address().encode(),
                            blocknumber=3,
                            headerhash=tmp_block3.headerhash,
                            xmss=slave_xmss)
                        vote.sign(slave_xmss)
                        buffered_chain.add_vote(vote)
                        vote_metadata = buffered_chain.get_consensus(3)

                        tmp_block4 = Block.create(
                            staking_address=staking_address,
                            block_number=4,
                            reveal_hash=h0,
                            prevblock_headerhash=tmp_block3.headerhash,
                            transactions=[],
                            duplicate_transactions=OrderedDict(),
                            vote=vote_metadata,
                            signing_xmss=slave_xmss,
                            nonce=4)

                    res = buffered_chain.add_block(block=tmp_block4)
                    self.assertTrue(res)

                    token_metadata = buffered_chain.get_token_metadata(
                        token_transaction.txhash)

                    self.assertEqual(token_metadata.token_txhash,
                                     token_transaction.txhash)
                    self.assertEqual(
                        len(token_metadata.transfer_token_tx_hashes), 3)
                    self.assertEqual(
                        token_metadata.transfer_token_tx_hashes[0],
                        token_transaction.txhash)

                    random_xmss1_state = chain.pstate._get_address_state(
                        random_xmss1.get_address().encode())
                    random_xmss2_state = chain.pstate._get_address_state(
                        random_xmss2.get_address().encode())
                    alice_state = chain.pstate._get_address_state(
                        alice_xmss.get_address().encode())

                    self.assertEqual(
                        random_xmss1_state.tokens[bin2hstr(
                            token_transaction.txhash).encode()], 300000000)
                    self.assertEqual(
                        random_xmss2_state.tokens[bin2hstr(
                            token_transaction.txhash).encode()], 0)
                    self.assertEqual(
                        alice_state.tokens[bin2hstr(
                            token_transaction.txhash).encode()], 300000000)
                    self.assertEqual(random_xmss1_state.balance,
                                     config.dev.default_account_balance - 13)
                    self.assertEqual(random_xmss2_state.balance,
                                     config.dev.default_account_balance + 9)
Example #28
0
    def test_getObject(self):
        SOME_ODD_HASH = sha256(b'this should not be found')
        SOME_ADDR1 = b'Q' + sha256(b'address1')
        SOME_ADDR2 = b'Q' + sha256(b'address2')

        db_state = Mock(spec=State)

        p2p_factory = Mock(spec=P2PFactory)
        buffered_chain = Mock(spec=BufferedChain)
        buffered_chain.tx_pool = Mock()
        buffered_chain.tx_pool.transaction_pool = []

        qrlnode = QRLNode(db_state)
        qrlnode.set_p2pfactory(p2p_factory)
        qrlnode.set_chain(buffered_chain)
        qrlnode._peer_addresses = ['127.0.0.1', '192.168.1.1']

        service = PublicAPIService(qrlnode)

        context = Mock(spec=ServicerContext)
        request = qrl_pb2.GetObjectReq()
        response = service.GetObject(request=request, context=context)
        context.set_code.assert_not_called()
        context.set_details.assert_not_called()
        self.assertFalse(response.found)

        # Find an address
        db_state.get_address = MagicMock(return_value=AddressState.create(
            address=SOME_ADDR1,
            nonce=25,
            balance=10,
            pubhashes=[sha256(b'a'), sha256(b'b')],
            tokens=dict()))
        db_state.get_address_tx_hashes = MagicMock(
            return_value=[sha256(b'0'), sha256(b'1')])

        context = Mock(spec=ServicerContext)
        request = qrl_pb2.GetObjectReq()
        request.query = SOME_ODD_HASH
        response = service.GetObject(request=request, context=context)
        context.set_code.assert_not_called()
        self.assertFalse(response.found)

        context = Mock(spec=ServicerContext)
        request = qrl_pb2.GetObjectReq()
        request.query = SOME_ADDR1
        response = service.GetObject(request=request, context=context)
        context.set_code.assert_not_called()
        self.assertTrue(response.found)
        self.assertIsNotNone(response.address_state)

        self.assertEqual(SOME_ADDR1, response.address_state.address)
        self.assertEqual(25, response.address_state.nonce)
        self.assertEqual(10, response.address_state.balance)
        self.assertEqual([sha256(b'a'), sha256(b'b')],
                         response.address_state.pubhashes)
        self.assertEqual([sha256(b'0'), sha256(b'1')],
                         response.address_state.transaction_hashes)

        # Find a transaction
        db_state.address_used = MagicMock(return_value=False)
        tx1 = TransferTransaction.create(addr_from=SOME_ADDR1,
                                         addr_to=SOME_ADDR2,
                                         amount=125,
                                         fee=19,
                                         xmss_pk=sha256(b'pk'),
                                         xmss_ots_index=13)

        buffered_chain.tx_pool.transaction_pool = [tx1]

        context = Mock(spec=ServicerContext)
        request = qrl_pb2.GetObjectReq()
        request.query = tx1.txhash
        response = service.GetObject(request=request, context=context)
        context.set_code.assert_not_called()
        self.assertTrue(response.found)
        self.assertIsNotNone(response.transaction)
        self.assertEqual(qrl_pb2.Transaction.TRANSFER,
                         response.transaction.type)
        self.assertEqual(SOME_ADDR1, response.transaction.addr_from)
        self.assertEqual(sha256(b'pk'), response.transaction.public_key)
        self.assertEqual(tx1.txhash, response.transaction.transaction_hash)
        self.assertEqual(13, response.transaction.ots_key)
        self.assertEqual(b'', response.transaction.signature)

        self.assertEqual(SOME_ADDR2, response.transaction.transfer.addr_to)
        self.assertEqual(125, response.transaction.transfer.amount)
        self.assertEqual(19, response.transaction.transfer.fee)

        # Find a block
        buffered_chain.get_block = MagicMock(return_value=Block.create(
            staking_address=qrladdress('staking_addr'),
            block_number=1,
            reveal_hash=sha256(b'reveal'),
            prevblock_headerhash=sha256(b'reveal'),
            transactions=[],
            duplicate_transactions=OrderedDict(),
            vote=VoteMetadata(),
            signing_xmss=get_alice_xmss(),
            nonce=1))

        context = Mock(spec=ServicerContext)
        request = qrl_pb2.GetObjectReq()
        request.query = bytes(str2bin('1'))
        response = service.GetObject(request=request, context=context)
        context.set_code.assert_not_called()
        self.assertTrue(response.found)
        self.assertIsNotNone(response.block)
        self.assertEqual(1, response.block.header.block_number)
Example #29
0
    def test_multi_output_transaction_add_block(self):
        with set_data_dir('no_data'):
            with State() as state:
                state.get_measurement = MagicMock(return_value=10000000)
                alice_xmss = get_alice_xmss()
                bob_xmss = get_bob_xmss()
                random_xmss = get_random_xmss()
                transfer_transaction = TransferTransaction.create(
                    addr_from=bob_xmss.address,
                    addrs_to=[alice_xmss.address, random_xmss.address],
                    amounts=[
                        40 * int(config.dev.shor_per_quanta),
                        59 * int(config.dev.shor_per_quanta)
                    ],
                    fee=1 * config.dev.shor_per_quanta,
                    xmss_pk=bob_xmss.pk)
                transfer_transaction._data.nonce = 1
                transfer_transaction.sign(bob_xmss)

                genesis_block = GenesisBlock()
                chain_manager = ChainManager(state)
                chain_manager.load(genesis_block)

                chain_manager._difficulty_tracker = Mock()
                dt = DifficultyTracker()
                tmp_difficulty = StringToUInt256('2')
                tmp_boundary = dt.get_target(tmp_difficulty)
                chain_manager._difficulty_tracker.get = MagicMock(
                    return_value=(tmp_difficulty, tmp_boundary))

                block = state.get_block(genesis_block.headerhash)
                self.assertIsNotNone(block)

                with mock.patch('qrl.core.misc.ntp.getTime') as time_mock:
                    time_mock.return_value = 1615270948  # Very high to get an easy difficulty

                    block_1 = Block.create(
                        block_number=1,
                        prevblock_headerhash=genesis_block.headerhash,
                        transactions=[transfer_transaction],
                        signing_xmss=alice_xmss,
                        master_address=alice_xmss.address,
                        nonce=1)

                    while not PoWValidator().validate_mining_nonce(
                            state, block_1.blockheader, False):
                        block_1.set_mining_nonce(block_1.mining_nonce + 1)

                    result = chain_manager.add_block(block_1)

                self.assertTrue(result)
                self.assertEqual(chain_manager.last_block, block_1)

                bob_addr_state = state.get_address(bob_xmss.address)
                alice_addr_state = state.get_address(alice_xmss.address)
                random_addr_state = state.get_address(random_xmss.address)

                self.assertEqual(bob_addr_state.balance, 0)
                self.assertEqual(
                    alice_addr_state.balance,
                    140 * int(config.dev.shor_per_quanta) +
                    block_1.block_reward + block_1.fee_reward)
                self.assertEqual(random_addr_state.balance,
                                 159 * int(config.dev.shor_per_quanta))
Example #30
0
    def test_getObject(self):
        SOME_ODD_HASH = sha256(b'this should not be found')

        db_state = Mock(spec=State)
        db_state.get_tx_metadata = MagicMock(return_value=None)
        db_state.get_block = MagicMock(return_value=None)

        p2p_factory = Mock(spec=P2PFactory)
        p2p_factory.pow = Mock(spec=POW)

        chain_manager = ChainManager(db_state)

        qrlnode = QRLNode(db_state, mining_address=b'')
        qrlnode.set_chain_manager(chain_manager)
        qrlnode._p2pfactory = p2p_factory
        qrlnode._pow = p2p_factory.pow
        qrlnode._peer_addresses = ['127.0.0.1', '192.168.1.1']

        service = PublicAPIService(qrlnode)

        # First try an empty request
        context = Mock(spec=ServicerContext)
        request = qrl_pb2.GetObjectReq()
        response = service.GetObject(request=request, context=context)
        context.set_code.assert_not_called()
        context.set_details.assert_not_called()
        self.assertFalse(response.found)

        # Some odd address
        context = Mock(spec=ServicerContext)
        request = qrl_pb2.GetObjectReq()
        request.query = SOME_ODD_HASH
        response = service.GetObject(request=request, context=context)
        context.set_code.assert_not_called()
        self.assertFalse(response.found)

        # Find an address
        addr1_state = AddressState.create(address=qrladdress('SOME_ADDR1'),
                                          nonce=25,
                                          balance=10,
                                          ots_bitfield=[b'\x00'] *
                                          config.dev.ots_bitfield_size,
                                          tokens=dict(),
                                          slave_pks_access_type=dict(),
                                          ots_counter=0)
        addr1_state.transaction_hashes.append(sha256(b'0'))
        addr1_state.transaction_hashes.append(sha256(b'1'))

        db_state.get_address_state = MagicMock(return_value=addr1_state)

        context = Mock(spec=ServicerContext)
        request = qrl_pb2.GetObjectReq()
        request.query = qrladdress('SOME_ADDR1')
        response = service.GetObject(request=request, context=context)
        context.set_code.assert_not_called()
        self.assertTrue(response.found)
        self.assertIsNotNone(response.address_state)

        self.assertEqual(qrladdress('SOME_ADDR1'),
                         response.address_state.address)
        self.assertEqual(25, response.address_state.nonce)
        self.assertEqual(10, response.address_state.balance)
        self.assertEqual([sha256(b'0'), sha256(b'1')],
                         response.address_state.transaction_hashes)

        # Find a transaction
        db_state.address_used = MagicMock(return_value=False)
        tx1 = TransferTransaction.create(addrs_to=[qrladdress('SOME_ADDR2')],
                                         amounts=[125],
                                         fee=19,
                                         xmss_pk=sha256(b'pk'),
                                         master_addr=qrladdress('SOME_ADDR1'))

        chain_manager.tx_pool.transaction_pool = [(0, TransactionInfo(tx1, 0))]

        context = Mock(spec=ServicerContext)
        request = qrl_pb2.GetObjectReq()
        request.query = tx1.txhash
        response = service.GetObject(request=request, context=context)
        context.set_code.assert_not_called()
        self.assertTrue(response.found)
        self.assertIsNotNone(response.transaction)
        self.assertEqual('transfer',
                         response.transaction.tx.WhichOneof('transactionType'))
        self.assertEqual(qrladdress('SOME_ADDR1'),
                         response.transaction.tx.master_addr)
        self.assertEqual(sha256(b'pk'), response.transaction.tx.public_key)
        self.assertEqual(tx1.txhash, response.transaction.tx.transaction_hash)
        self.assertEqual(b'', response.transaction.tx.signature)

        self.assertEqual(qrladdress('SOME_ADDR2'),
                         response.transaction.tx.transfer.addrs_to[0])
        self.assertEqual(125, response.transaction.tx.transfer.amounts[0])
        self.assertEqual(19, response.transaction.tx.fee)

        alice_xmss = get_alice_xmss()
        # Find a block
        db_state.get_block_by_number = MagicMock(
            return_value=Block.create(block_number=1,
                                      prev_block_headerhash=sha256(b'reveal'),
                                      prev_block_timestamp=10,
                                      transactions=[],
                                      miner_address=alice_xmss.address))

        context = Mock(spec=ServicerContext)
        request = qrl_pb2.GetObjectReq()
        request.query = bytes(str2bin('1'))
        response = service.GetObject(request=request, context=context)
        context.set_code.assert_not_called()
        self.assertTrue(response.found)
        self.assertIsNotNone(response.block_extended)
        self.assertEqual(1, response.block_extended.header.block_number)
Example #31
0
    def test_getLatestData(self):
        blocks = []
        txs = []
        alice_xmss = get_alice_xmss()
        for i in range(1, 4):
            for j in range(1, 3):
                txs.append(
                    TransferTransaction.create(addrs_to=[qrladdress('dest')],
                                               amounts=[i * 100 + j],
                                               fee=j,
                                               xmss_pk=alice_xmss.pk))

            blocks.append(
                Block.create(block_number=i,
                             prev_block_headerhash=sha256(b'reveal'),
                             prev_block_timestamp=10,
                             transactions=txs,
                             miner_address=alice_xmss.address))

        txpool = []
        for j in range(10, 15):
            tx = TransferTransaction.create(addrs_to=[qrladdress('dest')],
                                            amounts=[1000 + j],
                                            fee=j,
                                            xmss_pk=get_alice_xmss().pk)
            txpool.append((tx.fee, TransactionInfo(tx, 0)))

        db_state = Mock(spec=State)
        db_state.get_tx_metadata = MagicMock(return_value=None)
        db_state.get_last_txs = MagicMock(return_value=txs)

        p2p_factory = Mock(spec=P2PFactory)
        p2p_factory.pow = Mock(spec=POW)

        chain_manager = Mock(spec=ChainManager)
        chain_manager.get_block_by_number = Mock()
        chain_manager.get_block_by_number.side_effect = blocks
        chain_manager.tx_pool = Mock()
        chain_manager.tx_pool.transactions = heapq.nlargest(
            len(txpool), txpool)
        chain_manager.tx_pool.transaction_pool = txpool
        chain_manager.height = len(blocks)

        qrlnode = QRLNode(db_state, mining_address=b'')
        qrlnode.set_chain_manager(chain_manager)
        qrlnode.get_block_from_index = MagicMock(return_value=None)

        qrlnode._p2pfactory = p2p_factory
        qrlnode._pow = p2p_factory.pow

        service = PublicAPIService(qrlnode)
        context = Mock(spec=ServicerContext)

        request = qrl_pb2.GetLatestDataReq(filter=qrl_pb2.GetLatestDataReq.ALL,
                                           offset=1,
                                           quantity=3)

        response = service.GetLatestData(request=request, context=context)

        context.set_code.assert_not_called()
        context.set_details.assert_not_called()

        # Verify blockheaders
        self.assertEqual(3, len(response.blockheaders))
        self.assertEqual(1, response.blockheaders[0].header.block_number)
        self.assertEqual(2, response.blockheaders[1].header.block_number)
        self.assertEqual(3, response.blockheaders[2].header.block_number)

        # Verify transactions_unconfirmed
        self.assertEqual(3, len(response.transactions_unconfirmed))
        # TODO: Verify expected order
        self.assertEqual(
            1013, response.transactions_unconfirmed[0].tx.transfer.amounts[0])
        self.assertEqual(
            1012, response.transactions_unconfirmed[1].tx.transfer.amounts[0])
        self.assertEqual(
            1011, response.transactions_unconfirmed[2].tx.transfer.amounts[0])

        # Verify transactions
        self.assertEqual(3, len(response.transactions))
        self.assertEqual(2, response.transactions[0].tx.fee)
        self.assertEqual(1, response.transactions[1].tx.fee)
        self.assertEqual(2, response.transactions[2].tx.fee)

        self.assertEqual(102, response.transactions[0].tx.transfer.amounts[0])
        self.assertEqual(201, response.transactions[1].tx.transfer.amounts[0])
        self.assertEqual(202, response.transactions[2].tx.transfer.amounts[0])
Example #32
0
    def test_multi_output_transaction_add_block(self):
        with set_data_dir('no_data'):
            with State() as state:
                state.get_measurement = MagicMock(return_value=10000000)
                alice_xmss = get_alice_xmss()
                bob_xmss = get_bob_xmss()
                extended_seed = "010300cebc4e25553afa0aab899f7838e59e18a48852fa9dfd5" \
                                "ae78278c371902aa9e6e9c1fa8a196d2dba0cbfd2f2d212d16c"
                random_xmss = XMSS.from_extended_seed(hstr2bin(extended_seed))

                transfer_transaction = TransferTransaction.create(
                    addrs_to=[alice_xmss.address, random_xmss.address],
                    amounts=[
                        40 * int(config.dev.shor_per_quanta),
                        59 * int(config.dev.shor_per_quanta)
                    ],
                    fee=1 * config.dev.shor_per_quanta,
                    xmss_pk=bob_xmss.pk)
                transfer_transaction._data.nonce = 1
                transfer_transaction.sign(bob_xmss)

                genesis_block = GenesisBlock()
                chain_manager = ChainManager(state)
                chain_manager.load(genesis_block)

                chain_manager._difficulty_tracker = Mock()
                dt = DifficultyTracker()
                tmp_difficulty = StringToUInt256('2')
                tmp_boundary = dt.get_target(tmp_difficulty)
                chain_manager._difficulty_tracker.get = MagicMock(
                    return_value=(tmp_difficulty, tmp_boundary))

                block = state.get_block(genesis_block.headerhash)
                self.assertIsNotNone(block)

                with mock.patch('qrl.core.misc.ntp.getTime') as time_mock:
                    time_mock.return_value = 1615270948  # Very high to get an easy difficulty

                    block_1 = Block.create(
                        block_number=1,
                        prevblock_headerhash=genesis_block.headerhash,
                        transactions=[transfer_transaction],
                        miner_address=alice_xmss.address)
                    block_1.set_nonces(274, 0)

                    # Uncomment only to determine the correct mining_nonce of above blocks
                    # from qrl.core.PoWValidator import PoWValidator
                    # while not PoWValidator().validate_mining_nonce(state, block_1.blockheader, False):
                    #     block_1.set_nonces(block_1.mining_nonce + 1)
                    #     print(block_1.mining_nonce)

                    result = chain_manager.add_block(block_1)

                self.assertTrue(result)
                self.assertEqual(chain_manager.last_block, block_1)

                bob_addr_state = state.get_address(bob_xmss.address)
                alice_addr_state = state.get_address(alice_xmss.address)
                random_addr_state = state.get_address(random_xmss.address)

                self.assertEqual(bob_addr_state.balance, 0)
                self.assertEqual(
                    alice_addr_state.balance,
                    140 * int(config.dev.shor_per_quanta) +
                    block_1.block_reward + block_1.fee_reward)
                self.assertEqual(random_addr_state.balance,
                                 159 * int(config.dev.shor_per_quanta))