def test_set_affected_address(self, m_logger):
        result = set()
        params = self.default_params()
        tx = TransferTokenTransaction.create(**params)
        tx.set_affected_address(result)
        self.assertEqual(2, len(result))

        params = self.default_params()
        params["addrs_to"] = [self.bob.address, get_slave_xmss().address]
        params["amounts"] = [100, 200]
        tx = TransferTokenTransaction.create(**params)
        tx.set_affected_address(result)
        self.assertEqual(3, len(result))
 def test_create(self, m_logger):
     tx = TransferTokenTransaction.create(token_txhash=b'000000000000000',
                                          addrs_to=[self.bob.address],
                                          amounts=[200000],
                                          fee=1,
                                          xmss_pk=self.alice.pk)
     self.assertTrue(tx)
    def test_apply_state_changes(self, m_logger, m_apply_state_PK,
                                 m_revert_state_PK):
        """
        Alice has 1000 tokens and 100 QRL, Bob has none. Alice sends some tokens to Bob.
        """
        tx = TransferTokenTransaction.create(**self.params)
        tx.sign(self.alice)
        addresses_state = self.generate_addresses_state(tx)
        tx.apply_state_changes(addresses_state)

        self.assertEqual(addresses_state[self.alice.address].balance, 99)
        self.assertEqual(addresses_state[self.bob.address].balance, 0)
        addresses_state[
            self.alice.address].update_token_balance.assert_called_with(
                b'I declare the TEST token', -100)
        addresses_state[
            self.bob.address].update_token_balance.assert_called_with(
                b'I declare the TEST token', 100)
        self.assertEqual(
            [tx.txhash],
            addresses_state[self.alice.address].transaction_hashes)
        self.assertEqual([tx.txhash],
                         addresses_state[self.bob.address].transaction_hashes)

        m_apply_state_PK.assert_called_once()
Exemplo n.º 4
0
    def test_remove_transfer_token_metadata(self):
        with set_qrl_dir('no_data'):
            with State() as state:
                alice_xmss = get_alice_xmss()
                bob_xmss = get_bob_xmss()

                token_transaction = get_token_transaction(alice_xmss, bob_xmss)
                state.create_token_metadata(token_transaction)

                transfer_token = TransferTokenTransaction.create(token_txhash=token_transaction.txhash,
                                                                 addrs_to=[alice_xmss.address],
                                                                 amounts=[100000000],
                                                                 fee=1,
                                                                 xmss_pk=bob_xmss.pk)
                transfer_token.sign(alice_xmss)

                state.update_token_metadata(transfer_token)
                token_metadata = state.get_token_metadata(transfer_token.token_txhash)
                self.assertIn(transfer_token.txhash,
                              token_metadata.transfer_token_tx_hashes)

                state.remove_transfer_token_metadata(transfer_token)
                token_metadata = state.get_token_metadata(transfer_token.token_txhash)
                self.assertNotIn(transfer_token.txhash,
                                 token_metadata.transfer_token_tx_hashes)
    def test_revert_state_changes(self, m_logger, m_apply_state_PK,
                                  m_revert_state_PK):
        """
        Alice has 1000 tokens and 100 QRL, Bob has none. Alice sends some tokens to Bob.
        Let's undo this.
        """
        tx = TransferTokenTransaction.create(**self.params)
        tx.sign(self.alice)
        addresses_state = self.generate_addresses_state(tx)
        addresses_state[self.alice.address].balance = 99
        addresses_state[self.alice.address].tokens[
            self.params["token_txhash"]] = 900
        addresses_state[self.alice.address].transaction_hashes = [tx.txhash]
        addresses_state[self.bob.address].balance = 0
        addresses_state[self.bob.address].tokens[
            self.params["token_txhash"]] = 100
        addresses_state[self.bob.address].transaction_hashes = [tx.txhash]

        tx.revert_state_changes(addresses_state,
                                self.unused_chain_manager_mock)

        self.assertEqual(addresses_state[self.alice.address].balance, 100)
        self.assertEqual(addresses_state[self.bob.address].balance, 0)
        addresses_state[
            self.alice.address].update_token_balance.assert_called_with(
                b'I declare the TEST token', 100)
        addresses_state[
            self.bob.address].update_token_balance.assert_called_with(
                b'I declare the TEST token', -100)
        self.assertEqual(
            [], addresses_state[self.alice.address].transaction_hashes)
        self.assertEqual([],
                         addresses_state[self.bob.address].transaction_hashes)

        m_revert_state_PK.assert_called_once()
Exemplo n.º 6
0
    def test_remove_transfer_token_metadata(self):
        alice_xmss = get_alice_xmss()
        bob_xmss = get_bob_xmss()

        token_transaction = get_token_transaction(alice_xmss, bob_xmss)
        TokenMetadata.create_token_metadata(self.state, token_transaction,
                                            None)

        transfer_token = TransferTokenTransaction.create(
            token_txhash=token_transaction.txhash,
            addrs_to=[alice_xmss.address],
            amounts=[100000000],
            fee=1,
            xmss_pk=bob_xmss.pk)
        transfer_token.sign(alice_xmss)

        TokenMetadata.update_token_metadata(self.state, transfer_token, None)
        token_metadata = TokenMetadata.get_token_metadata(
            self.state, transfer_token.token_txhash)
        self.assertIn(transfer_token.txhash,
                      token_metadata.transfer_token_tx_hashes)

        TokenMetadata.remove_transfer_token_metadata(self.state,
                                                     transfer_token, None)
        token_metadata = TokenMetadata.get_token_metadata(
            self.state, transfer_token.token_txhash)
        self.assertNotIn(transfer_token.txhash,
                         token_metadata.transfer_token_tx_hashes)
Exemplo n.º 7
0
    def test_to_json(self, m_logger):
        tx = TransferTokenTransaction.create(token_txhash=b'000000000000000',
                                             addrs_to=[self.bob.address],
                                             amounts=[200000],
                                             fee=1,
                                             xmss_pk=self.alice.pk)
        txjson = tx.to_json()

        self.assertEqual(json.loads(test_json_TransferToken), json.loads(txjson))
Exemplo n.º 8
0
def tx_transfertoken(ctx, src, master, token_txhash, dsts, amounts, decimals,
                     fee, ots_key_index):
    """
    Create Transfer Token Transaction, which moves tokens from src to dst.
    """

    if decimals > 19:
        click.echo(
            "The number of decimal cannot exceed 19 under any configuration")
        quit(1)

    try:
        addresses_dst, shor_amounts = _parse_dsts_amounts(
            dsts, amounts, token_decimals=decimals)
        bin_token_txhash = parse_hexblob(token_txhash)
        master_addr = None
        if master:
            master_addr = parse_qaddress(master)
        # FIXME: This could be problematic. Check
        fee_shor = _quanta_to_shor(fee)

        _, src_xmss = _select_wallet(ctx, src)
        if not src_xmss:
            click.echo("A local wallet is required to sign the transaction")
            quit(1)

        address_src_pk = src_xmss.pk

        ots_key_index = validate_ots_index(ots_key_index, src_xmss)
        src_xmss.set_ots_index(ots_key_index)

    except KeyboardInterrupt:
        click.echo("Terminated by user")
        quit(1)
    except Exception as e:
        click.echo("Error validating arguments: {}".format(e))
        quit(1)

    try:
        stub = ctx.obj.get_stub_public_api()
        tx = TransferTokenTransaction.create(token_txhash=bin_token_txhash,
                                             addrs_to=addresses_dst,
                                             amounts=shor_amounts,
                                             fee=fee_shor,
                                             xmss_pk=address_src_pk,
                                             master_addr=master_addr)
        tx.sign(src_xmss)

        push_transaction_req = qrl_pb2.PushTransactionReq(
            transaction_signed=tx.pbdata)
        push_transaction_resp = stub.PushTransaction(
            push_transaction_req, timeout=CONNECTION_TIMEOUT)

        print(push_transaction_resp.error_code)
    except Exception as e:
        print("Error {}".format(str(e)))
Exemplo n.º 9
0
 def test_broadcast_tx(self, m_reactor, m_logger):
     # broadcast_tx() should handle all Transaction Types
     self.factory.broadcast_tx(MessageTransaction())
     self.factory.broadcast_tx(TransferTransaction())
     self.factory.broadcast_tx(TokenTransaction())
     self.factory.broadcast_tx(TransferTokenTransaction())
     self.factory.broadcast_tx(SlaveTransaction())
     with self.assertRaises(ValueError):
         m_tx = Mock(autospec=TransferTransaction, txhash=bhstr2bin('deadbeef'))
         self.factory.broadcast_tx(m_tx)
    def test_revert_transfer_token_txn_multi_send(self):
        """
        Alice has 1100 tokens and 100 QRL, Bob and Slave have none. Alice sends some tokens to Bob and Slave.
        Undo this.
        """
        slave = get_slave_xmss()
        self.params["addrs_to"] = [self.bob.address, slave.address]
        self.params["amounts"] = [100, 100]

        tx = TransferTokenTransaction.create(**self.params)
        tx.sign(self.alice)
        addresses_state = dict(self.addresses_state)
        addresses_state[self.alice.address].pbdata.balance = 100
        addresses_state[self.bob.address].pbdata.balance = 0
        addresses_state[slave.address] = OptimizedAddressState.get_default(
            slave.address)
        tokens = Indexer(b'token', None)
        tokens.data[(self.alice.address,
                     tx.token_txhash)] = TokenBalance(balance=1100)

        state_container = StateContainer(addresses_state=addresses_state,
                                         tokens=tokens,
                                         slaves=Indexer(b'slave', None),
                                         lattice_pk=Indexer(
                                             b'lattice_pk', None),
                                         multi_sig_spend_txs=dict(),
                                         votes_stats=dict(),
                                         block_number=1,
                                         total_coin_supply=1000,
                                         current_dev_config=config.dev,
                                         write_access=True,
                                         my_db=self.state._db,
                                         batch=None)
        state_container.paginated_bitfield.set_ots_key(addresses_state,
                                                       self.alice.address, 0)

        self.assertTrue(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.alice.address, 0))
        tx.apply(self.state, state_container)
        tx.revert(self.state, state_container)
        self.assertFalse(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.alice.address, 0))

        self.assertEqual(addresses_state[self.alice.address].balance, 100)
        self.assertEqual(addresses_state[self.bob.address].balance, 0)
        self.assertEqual(addresses_state[slave.address].balance, 0)

        self.assertEqual(
            tokens.data[(self.alice.address, tx.token_txhash)].balance, 1100)
        self.assertEqual(
            tokens.data[(self.bob.address, tx.token_txhash)].balance, 0)
        self.assertEqual(tokens.data[(slave.address, tx.token_txhash)].balance,
                         0)
    def test_validate_tx2(self, m_logger):
        params = self.default_params()
        tx = TransferTokenTransaction.create(**params)
        tx.sign(self.alice)

        self.assertTrue(tx.validate_or_raise())

        tx._data.transaction_hash = b'abc'

        # Should fail, as we have modified with invalid transaction_hash
        with self.assertRaises(ValueError):
            tx.validate_or_raise()
Exemplo n.º 12
0
 def create_transfer_token_txn(addrs_to: list,
                               token_txhash: bytes,
                               amounts: list,
                               fee: int,
                               xmss_pk: bytes,
                               master_addr: bytes):
     return TransferTokenTransaction.create(token_txhash,
                                            addrs_to,
                                            amounts,
                                            fee,
                                            xmss_pk,
                                            master_addr)
    def test_validate_tx(self, m_logger):
        tx = TransferTokenTransaction.create(token_txhash=b'000000000000000',
                                             addrs_to=[self.bob.address],
                                             amounts=[200000],
                                             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())
    def test_apply_state_changes_empty_addresses_state(self, m_logger,
                                                       m_apply_state_PK,
                                                       m_revert_state_PK):
        """
        Alice has 1000 tokens and 100 QRL, Bob has none. Alice sends some tokens to Bob.
        But this node has no AddressState corresponding to these parties.
        """
        tx = TransferTokenTransaction.create(**self.params)
        tx.sign(self.alice)
        addresses_state = {}
        tx.apply_state_changes(addresses_state)

        self.assertEqual({}, addresses_state)
        m_apply_state_PK.assert_called_once()
    def test_revert_state_changes_empty_addresses_state(
            self, m_logger, m_apply_state_PK, m_revert_state_PK):
        """
        If we didn't have any AddressStates for the addresses involved in this test, do nothing
        """
        tx = TransferTokenTransaction.create(**self.params)
        tx.sign(self.alice)
        addresses_state = {}

        tx.revert_state_changes(addresses_state,
                                self.unused_chain_manager_mock)

        self.assertEqual(addresses_state, {})
        m_revert_state_PK.assert_called_once()
    def test_revert_state_changes_multi_send(self, m_logger, m_apply_state_PK,
                                             m_revert_state_PK):
        """
        Alice has 1000 tokens and 100 QRL, Bob and Slave have none. Alice sends some tokens to Bob and Slave.
        Undo this.
        """
        slave = get_slave_xmss()
        self.params["addrs_to"] = [self.bob.address, slave.address]
        self.params["amounts"] = [100, 100]

        tx = TransferTokenTransaction.create(**self.params)
        tx.sign(self.alice)
        addresses_state = self.generate_addresses_state(tx)
        addresses_state[self.alice.address].balance = 99
        addresses_state[self.alice.address].tokens[
            self.params["token_txhash"]] = 900
        addresses_state[self.alice.address].transaction_hashes = [tx.txhash]
        addresses_state[self.bob.address].balance = 0
        addresses_state[self.bob.address].tokens[
            self.params["token_txhash"]] = 100
        addresses_state[self.bob.address].transaction_hashes = [tx.txhash]
        addresses_state[slave.address] = Mock(
            autospec=AddressState,
            name='slave AddressState',
            tokens={self.params["token_txhash"]: 100},
            transaction_hashes=[tx.txhash],
            balance=0)

        tx.revert_state_changes(addresses_state,
                                self.unused_chain_manager_mock)

        self.assertEqual(addresses_state[self.alice.address].balance, 100)
        self.assertEqual(addresses_state[self.bob.address].balance, 0)
        self.assertEqual(addresses_state[slave.address].balance, 0)
        addresses_state[
            self.alice.address].update_token_balance.assert_called_with(
                b'I declare the TEST token', 200)
        addresses_state[
            self.bob.address].update_token_balance.assert_called_with(
                b'I declare the TEST token', -100)
        addresses_state[slave.address].update_token_balance.assert_called_with(
            b'I declare the TEST token', -100)
        self.assertEqual(
            [], addresses_state[self.alice.address].transaction_hashes)
        self.assertEqual([],
                         addresses_state[self.bob.address].transaction_hashes)
        self.assertEqual([], addresses_state[slave.address].transaction_hashes)

        m_revert_state_PK.assert_called_once()
Exemplo n.º 17
0
    def test_state_validate_tx_custom(self, m_logger):
        """
        TransferTokenTransaction._validate_custom() checks for:
        1. 0 amounts
        2. fee < 0
        3. multi-send: too many recipients
        4. multi-send: recipient addresses and amounts not the same length
        5. invalid addr_from
        6. invalid addr_to
        """
        slave = get_slave_xmss()
        params = self.default_params()
        tx = TransferTokenTransaction.create(**params)
        tx.sign(self.alice)

        result = tx.validate_or_raise()
        self.assertTrue(result)

        params = self.default_params()
        params["addrs_to"] = [self.bob.address, slave.address]
        params["amounts"] = [1, 0]
        with self.assertRaises(ValueError):
            tx = TransferTokenTransaction.create(**params)

        # Protobuf validation doesn't allow negative fees already
        params = self.default_params()
        tx = TransferTokenTransaction.create(**params)
        tx.sign(self.alice)
        with patch('qrl.core.txs.Transaction.Transaction.fee', new_callable=PropertyMock) as m_fee:
            m_fee.return_value = -1
            with self.assertRaises(ValueError):
                tx.validate_or_raise()

        # TX signing already fails if addrs_to and amounts are unequal length
        params = self.default_params()
        tx = TransferTokenTransaction.create(**params)
        tx.sign(self.alice)
        with patch('qrl.core.txs.TransferTokenTransaction.TransferTokenTransaction.addrs_to',
                   new_callable=PropertyMock) as m_addrs_to:
            m_addrs_to.return_value = [self.bob.address, slave.address]
            with self.assertRaises(ValueError):
                tx.validate_or_raise()

        params = self.default_params()
        params["master_addr"] = b'Bad QRL Address'
        with self.assertRaises(ValueError):
            tx = TransferTokenTransaction.create(**params)

        params = self.default_params()
        params["addrs_to"] = [self.bob.address, b'Bad QRL address']
        params["amounts"] = [100, 200]
        with self.assertRaises(ValueError):
            tx = TransferTokenTransaction.create(**params)
Exemplo n.º 18
0
    def relay_transfer_token_txn(self, qaddresses_to: list, amounts: list,
                                 token_txhash: str, fee: int, master_qaddress,
                                 signer_address: str, ots_index: int):
        self.authenticate()
        index, xmss = self._get_wallet_index_xmss(signer_address, ots_index)

        tx = TransferTokenTransaction.create(
            token_txhash=bytes(hstr2bin(token_txhash)),
            addrs_to=self.qaddresses_to_address(qaddresses_to),
            amounts=amounts,
            fee=fee,
            xmss_pk=xmss.pk,
            master_addr=self.qaddress_to_address(master_qaddress))

        self._push_transaction(tx, xmss)
        self._wallet.set_ots_index(index, xmss.ots_index)

        return self.to_plain_transaction(tx.pbdata)
    def test_apply_state_changes_send_tokens_to_self(self, m_logger,
                                                     m_apply_state_PK,
                                                     m_revert_state_PK):
        """
        Alice has 1000 tokens and 100 QRL. She sends some tokens to herself. What happens next?
        """
        self.params["addrs_to"] = [self.alice.address]
        tx = TransferTokenTransaction.create(**self.params)
        tx.sign(self.alice)
        addresses_state = self.generate_addresses_state(tx)
        tx.apply_state_changes(addresses_state)

        self.assertEqual(addresses_state[self.alice.address].balance, 99)
        # Unfortunately importing mock.call results in some sort of ValueError so I can't check the arguments.
        self.assertEqual(
            addresses_state[
                self.alice.address].update_token_balance.call_count, 2)

        m_apply_state_PK.assert_called_once()
    def test_revert_transfer_token_txn_send_tokens_to_self(self):
        """
        Alice has 1000 tokens and 100 QRL. She sends some tokens to herself.
        Can we undo this?
        """
        self.params["addrs_to"] = [self.alice.address]
        tx = TransferTokenTransaction.create(**self.params)
        tx.sign(self.alice)
        addresses_state = dict(self.addresses_state)
        addresses_state[self.alice.address].pbdata.balance = 100
        tokens = Indexer(b'token', None)
        tokens.data[(self.alice.address,
                     tx.token_txhash)] = TokenBalance(balance=100)
        state_container = StateContainer(addresses_state=addresses_state,
                                         tokens=tokens,
                                         slaves=Indexer(b'slave', None),
                                         lattice_pk=Indexer(
                                             b'lattice_pk', None),
                                         multi_sig_spend_txs=dict(),
                                         votes_stats=dict(),
                                         block_number=1,
                                         total_coin_supply=1000,
                                         current_dev_config=config.dev,
                                         write_access=True,
                                         my_db=self.state._db,
                                         batch=None)
        state_container.paginated_bitfield.set_ots_key(addresses_state,
                                                       self.alice.address, 0)

        self.assertTrue(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.alice.address, 0))
        tx.apply(self.state, state_container)
        tx.revert(self.state, state_container)
        self.assertFalse(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.alice.address, 0))

        self.assertEqual(addresses_state[self.alice.address].balance, 100)
        # Unfortunately importing mock.call results in some sort of ValueError so I can't check the arguments.
        self.assertEqual(
            tokens.data[(self.alice.address, tx.token_txhash)].balance, 100)
Exemplo n.º 21
0
    def relay_transfer_token_txn_by_slave(self, qaddresses_to: list,
                                          amounts: list, token_txhash: str,
                                          fee: int, master_qaddress):
        self.authenticate()
        index, group_index, slave_index, slave_xmss = self.get_slave_xmss(
            master_qaddress)
        if slave_index == -1:
            raise Exception("No Slave Found")

        tx = TransferTokenTransaction.create(
            token_txhash=bytes(hstr2bin(token_txhash)),
            addrs_to=self.qaddresses_to_address(qaddresses_to),
            amounts=amounts,
            fee=fee,
            xmss_pk=slave_xmss.pk,
            master_addr=self.qaddress_to_address(master_qaddress))

        self.sign_and_push_transaction(tx, slave_xmss, index, group_index,
                                       slave_index)

        return self.to_plain_transaction(tx.pbdata)
    def test_apply_transfer_token_txn(self):
        """
        Alice has 1000 tokens and 100 QRL, Bob has none. Alice sends some tokens to Bob.
        """
        tx = TransferTokenTransaction.create(**self.params)
        tx.sign(self.alice)
        addresses_state = dict(self.addresses_state)
        tokens = Indexer(b'token', None)
        tokens.data[(self.alice.address,
                     tx.token_txhash)] = TokenBalance(balance=150)
        tokens.data[(self.bob.address,
                     tx.token_txhash)] = TokenBalance(balance=0)
        state_container = StateContainer(addresses_state=addresses_state,
                                         tokens=tokens,
                                         slaves=Indexer(b'slave', None),
                                         lattice_pk=Indexer(
                                             b'lattice_pk', None),
                                         multi_sig_spend_txs=dict(),
                                         votes_stats=dict(),
                                         block_number=1,
                                         total_coin_supply=1000,
                                         current_dev_config=config.dev,
                                         write_access=True,
                                         my_db=self.state._db,
                                         batch=None)
        self.assertFalse(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.alice.address, 0))
        tx.apply(self.state, state_container)
        self.assertTrue(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.alice.address, 0))

        self.assertEqual(addresses_state[self.alice.address].balance, 99)
        self.assertEqual(addresses_state[self.bob.address].balance, 0)

        self.assertEqual(
            tokens.data[(self.alice.address, tx.token_txhash)].balance, 50)
        self.assertEqual(
            tokens.data[(self.bob.address, tx.token_txhash)].balance, 100)
    def test_revert_transfer_token_txn_empty_addresses_state(self):
        """
        If we didn't have any AddressStates for the addresses involved in this test, do nothing
        """
        tx = TransferTokenTransaction.create(**self.params)
        tx.sign(self.alice)
        addresses_state = dict(self.addresses_state)
        tokens = Indexer(b'token', None)
        tokens.data[(self.alice.address,
                     tx.token_txhash)] = TokenBalance(balance=100)
        state_container = StateContainer(addresses_state=addresses_state,
                                         tokens=tokens,
                                         slaves=Indexer(b'slave', None),
                                         lattice_pk=Indexer(
                                             b'lattice_pk', None),
                                         multi_sig_spend_txs=dict(),
                                         votes_stats=dict(),
                                         block_number=1,
                                         total_coin_supply=1000,
                                         current_dev_config=config.dev,
                                         write_access=True,
                                         my_db=self.state._db,
                                         batch=None)
        state_container.paginated_bitfield.set_ots_key(addresses_state,
                                                       self.alice.address, 0)

        self.assertTrue(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.alice.address, 0))
        tx.apply(self.state, state_container)
        tx.revert(self.state, state_container)
        self.assertFalse(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.alice.address, 0))

        self.assertEqual(
            100, tokens.data[(self.alice.address, tx.token_txhash)].balance)
        self.assertEqual(
            0, tokens.data[(self.bob.address, tx.token_txhash)].balance)
    def test_revert_state_changes_send_tokens_to_self(self, m_logger,
                                                      m_apply_state_PK,
                                                      m_revert_state_PK):
        """
        Alice has 1000 tokens and 100 QRL. She sends some tokens to herself.
        Can we undo this?
        """
        self.params["addrs_to"] = [self.alice.address]
        tx = TransferTokenTransaction.create(**self.params)
        tx.sign(self.alice)
        addresses_state = self.generate_addresses_state(tx)
        addresses_state[self.alice.address].balance = 99
        addresses_state[self.alice.address].transaction_hashes = [tx.txhash]
        tx.revert_state_changes(addresses_state,
                                self.unused_chain_manager_mock)

        self.assertEqual(addresses_state[self.alice.address].balance, 100)
        # Unfortunately importing mock.call results in some sort of ValueError so I can't check the arguments.
        self.assertEqual(
            addresses_state[
                self.alice.address].update_token_balance.call_count, 2)

        m_revert_state_PK.assert_called_once()
Exemplo n.º 25
0
    def test_update_token_metadata(self):
        alice_xmss = get_alice_xmss()
        bob_xmss = get_bob_xmss()

        token_transaction = get_token_transaction(alice_xmss, bob_xmss)
        self.state.create_token_metadata(token_transaction)

        transfer_token_transaction = TransferTokenTransaction.create(
            token_txhash=token_transaction.txhash,
            addrs_to=[alice_xmss.address],
            amounts=[100000000],
            fee=1,
            xmss_pk=bob_xmss.pk)

        self.state.update_token_metadata(transfer_token_transaction)

        token_metadata = self.state.get_token_metadata(
            token_transaction.txhash)
        self.assertEqual(len(token_metadata.transfer_token_tx_hashes), 2)
        self.assertEqual(token_metadata.transfer_token_tx_hashes[0],
                         token_transaction.txhash)
        self.assertEqual(token_metadata.transfer_token_tx_hashes[1],
                         transfer_token_transaction.txhash)
Exemplo n.º 26
0
    def test_validate_extended(self, m_validate_slave, m_logger):
        """
        TransferTokenTransaction._validate_extended checks for:
        1. valid master/slave
        2. negative fee, negative total token amounts transferred
        3. addr_from has enough funds for the fee
        4. if addr_from owns any tokens to begin with
        5. if addr_from has enough tokens
        6. addr_from ots_key reuse
        """
        alice_address_state = OptimizedAddressState.get_default(self.alice.address)
        alice_address_state.pbdata.balance = 100

        params = self.default_params()
        tx = TransferTokenTransaction.create(**params)
        tx.sign(self.alice)

        addresses_state = {
            alice_address_state.address: alice_address_state
        }
        tokens = Indexer(b'token', None)
        tokens.data[(self.alice.address, tx.token_txhash)] = qrl_pb2.TokenBalance(balance=1000,
                                                                                  decimals=0,
                                                                                  delete=False)

        state_container = StateContainer(addresses_state=addresses_state,
                                         tokens=tokens,
                                         slaves=Indexer(b'slave', None),
                                         lattice_pk=Indexer(b'lattice_pk', None),
                                         multi_sig_spend_txs=dict(),
                                         votes_stats=dict(),
                                         block_number=1,
                                         total_coin_supply=1000,
                                         current_dev_config=config.dev,
                                         write_access=True,
                                         my_db=self.state._db,
                                         batch=None)
        result = tx._validate_extended(state_container)
        self.assertTrue(result)

        # Invalid master XMSS/slave XMSS relationship
        m_validate_slave.return_value = False
        state_container.tokens = Indexer(b'token', None)
        state_container.tokens.data[(self.alice.address, tx.token_txhash)] = qrl_pb2.TokenBalance(balance=1000,
                                                                                                  decimals=0,
                                                                                                  delete=False)
        result = tx.validate_all(state_container)
        self.assertFalse(result)
        m_validate_slave.return_value = True

        # fee = -1
        with patch('qrl.core.txs.TransferTokenTransaction.TransferTokenTransaction.fee',
                   new_callable=PropertyMock) as m_fee:
            m_fee.return_value = -1
            tokens = Indexer(b'token', None)
            tokens.data[(self.alice.address, tx.token_txhash)] = qrl_pb2.TokenBalance(balance=1000,
                                                                                      decimals=0,
                                                                                      delete=False)
            state_container.tokens = tokens
            result = tx._validate_extended(state_container)
            self.assertFalse(result)

        # total_amount = -1
        with patch('qrl.core.txs.TransferTokenTransaction.TransferTokenTransaction.total_amount',
                   new_callable=PropertyMock) as m_total_amount:
            m_total_amount.return_value = -100
            tokens = Indexer(b'token', None)
            tokens.data[(self.alice.address, tx.token_txhash)] = qrl_pb2.TokenBalance(balance=1000,
                                                                                      decimals=0,
                                                                                      delete=False)
            state_container.tokens = tokens
            result = tx._validate_extended(state_container)
            self.assertFalse(result)

        # balance = 0, cannot pay the Transaction fee
        alice_address_state.pbdata.balance = 0
        tokens = Indexer(b'token', None)
        tokens.data[(self.alice.address, tx.token_txhash)] = qrl_pb2.TokenBalance(balance=1000,
                                                                                  decimals=0,
                                                                                  delete=False)
        state_container.tokens = tokens
        result = tx._validate_extended(state_container)
        self.assertFalse(result)
        alice_address_state.pbdata.balance = 100

        # addr_from doesn't have these tokens
        state_container.tokens = Indexer(b'token', None)
        result = tx._validate_extended(state_container)
        self.assertFalse(result)

        # addr_from doesn't have enough tokens
        tokens = Indexer(b'token', None)
        tokens.data[(self.alice.address, tx.token_txhash)] = qrl_pb2.TokenBalance(balance=99,
                                                                                  decimals=0,
                                                                                  delete=False)
        state_container.tokens = tokens
        result = tx._validate_extended(state_container)
        self.assertFalse(result)

        # addr_from_pk has used this OTS key before
        addresses_state = {
            self.alice.address: alice_address_state
        }
        state_container.addresses_state = addresses_state
        # addr_from_pk has used this OTS key before
        state_container.paginated_bitfield.set_ots_key(addresses_state, alice_address_state.address, tx.ots_key)
        result = tx.validate_all(state_container)
        self.assertFalse(result)

        slave = get_slave_xmss()
        params = self.default_params()
        params["addrs_to"] = [self.bob.address, slave.address, self.alice.address]
        params["amounts"] = [2, 3, 5]
        tx = TransferTokenTransaction.create(**params)
        tx.sign(self.alice)
        with patch('qrl.core.config', autospec=True) as m_config:
            m_config.dev = config.dev.create(config.dev.prev_state_key, config.dev.current_state_key,
                                             b'', 10, True, True)
            m_config.dev.pbdata.transaction.multi_output_limit = 1
            state_container.current_dev_config = m_config.dev
            self.assertFalse(tx._validate_extended(state_container=state_container))
    def test_validate_extended(self, m_validate_slave, m_logger):
        """
        TransferTokenTransaction.validate_extended checks for:
        1. valid master/slave
        2. negative fee, negative total token amounts transferred
        3. addr_from has enough funds for the fee
        4. if addr_from owns any tokens to begin with
        5. if addr_from has enough tokens
        6. addr_from ots_key reuse
        """
        m_addr_from_state = Mock(autospec=AddressState,
                                 name='addr_from State',
                                 balance=100)
        m_addr_from_state.is_token_exists.return_value = True
        m_addr_from_state.get_token_balance.return_value = 1000

        m_addr_from_pk_state = Mock(autospec=AddressState,
                                    name='addr_from_pk State')
        m_addr_from_pk_state.ots_key_reuse.return_value = False

        params = self.default_params()
        tx = TransferTokenTransaction.create(**params)
        tx.sign(self.alice)

        result = tx.validate_extended(m_addr_from_state, m_addr_from_pk_state)
        self.assertTrue(result)

        # Invalid master XMSS/slave XMSS relationship
        m_validate_slave.return_value = False
        result = tx.validate_extended(m_addr_from_state, m_addr_from_pk_state)
        self.assertFalse(result)
        m_validate_slave.return_value = True

        # fee = -1
        with patch(
                'qrl.core.txs.TransferTokenTransaction.TransferTokenTransaction.fee',
                new_callable=PropertyMock) as m_fee:
            m_fee.return_value = -1
            result = tx.validate_extended(m_addr_from_state,
                                          m_addr_from_pk_state)
            self.assertFalse(result)

        # total_amount = -1
        with patch(
                'qrl.core.txs.TransferTokenTransaction.TransferTokenTransaction.total_amount',
                new_callable=PropertyMock) as m_total_amount:
            m_total_amount.return_value = -100
            result = tx.validate_extended(m_addr_from_state,
                                          m_addr_from_pk_state)
            self.assertFalse(result)

        # balance = 0, cannot pay the Transaction fee
        m_addr_from_state.balance = 0
        result = tx.validate_extended(m_addr_from_state, m_addr_from_pk_state)
        self.assertFalse(result)
        m_addr_from_state.balance = 100

        # addr_from doesn't have these tokens
        m_addr_from_state.is_token_exists.return_value = False
        result = tx.validate_extended(m_addr_from_state, m_addr_from_pk_state)
        self.assertFalse(result)
        m_addr_from_state.is_token_exists.return_value = True

        # addr_from doesn't have enough tokens
        m_addr_from_state.get_token_balance.return_value = 99
        result = tx.validate_extended(m_addr_from_state, m_addr_from_pk_state)
        self.assertFalse(result)
        m_addr_from_state.get_token_balance.return_value = 1000

        # addr_from_pk has used this OTS key before
        m_addr_from_pk_state.ots_key_reuse.return_value = True
        result = tx.validate_extended(m_addr_from_state, m_addr_from_pk_state)
        self.assertFalse(result)