Example #1
0
    def test_validate_extended(self, m_validate_slave, m_logger):
        """
        Message._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. addr_from ots_key reuse
        """
        m_addr_from_state = Mock(autospec=OptimizedAddressState,
                                 name='addr_from State',
                                 balance=100)

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

        addresses_state = {self.alice.address: m_addr_from_state}

        tx = MessageTransaction.create(**self.params)
        tx.sign(self.alice)

        state_container = StateContainer(addresses_state=addresses_state,
                                         tokens=Indexer(b'token', None),
                                         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=100,
                                         current_dev_config=config.dev,
                                         write_access=True,
                                         my_db=None,
                                         batch=None)
        result = tx._validate_extended(state_container)
        self.assertTrue(result)

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

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

        self.params["message_hash"] = b'T' * 81

        # Validation should fail, as we have entered a message of more than 80 lengths
        tx = MessageTransaction.create(**self.params)
        self.assertFalse(tx._validate_extended(state_container))
Example #2
0
 def test_validate_slave_master_addr_same_as_signing_addr(self, m_logger):
     self.params["master_addr"] = self.alice.address
     tx = MessageTransaction.create(**self.params)
     tx.sign(self.alice)
     result = tx.validate_slave(self.m_addr_state,
                                self.m_addr_from_pk_state)
     self.assertFalse(result)
Example #3
0
    def test_revert_message_txn(self):
        tx = MessageTransaction.create(**self.params)
        tx.sign(self.alice)
        addresses_state = dict(self.addresses_state)

        state_container = StateContainer(addresses_state=addresses_state,
                                         tokens=Indexer(b'token', None),
                                         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=100,
                                         current_dev_config=config.dev,
                                         write_access=True,
                                         my_db=self.state._db,
                                         batch=None)
        tx.apply(self.state, state_container)
        tx.revert(self.state, state_container)

        self.assertEqual(addresses_state[self.alice.address].balance, 100)
        storage_key = state_container.paginated_tx_hash.generate_key(
            self.alice.address, 1)
        self.assertIn(storage_key, state_container.paginated_tx_hash.key_value)
        self.assertEqual(
            [], state_container.paginated_tx_hash.key_value[storage_key])
Example #4
0
 def create_message_txn(message_hash: bytes, addr_to: bytes, fee: int,
                        xmss_pk: bytes, master_addr: bytes):
     return MessageTransaction.create(message_hash=message_hash,
                                      addr_to=addr_to,
                                      fee=fee,
                                      xmss_pk=xmss_pk,
                                      master_addr=master_addr)
Example #5
0
    def test_validate_slave_has_insufficient_permissions(self, m_logger):
        """
        Master's AddressState says the Slave has permission 0.
        But Slave's AddressState says the Slave is good for permission 2.
        Therefore the Slave does not have enough permissions.
        """
        bob = get_bob_xmss()
        # Let's say Alice is Bob's master.
        self.params["master_addr"] = self.alice.address
        self.params["xmss_pk"] = bob.pk

        tx = MessageTransaction.create(**self.params)
        tx.sign(self.alice)

        # The master's state says the slave can have these permissions.
        self.m_addr_state.slave_pks_access_type = {str(tx.PK): 0}
        # The signing slave's state can be 0 (full permissions) or 1 (mining only) but only 0 is used for now.
        # Let's give an invalid number.
        self.m_addr_from_pk_state.slave_pks_access_type = {str(tx.PK): 2}
        result = tx.validate_slave(self.m_addr_state,
                                   self.m_addr_from_pk_state)
        self.assertFalse(result)

        # Let's give a valid number, that matches what the master's state says (0)
        self.m_addr_from_pk_state.slave_pks_access_type = {str(tx.PK): 0}
        result = tx.validate_slave(self.m_addr_state,
                                   self.m_addr_from_pk_state)
        self.assertTrue(result)
Example #6
0
    def test_to_json(self, m_logger):
        tx = MessageTransaction.create(message_hash=b'Test Message',
                                       fee=1,
                                       xmss_pk=self.alice.pk)
        txjson = tx.to_json()

        self.assertEqual(json.loads(test_json_MessageTransaction), json.loads(txjson))
    def test_revert_state_changes_empty_addresses_state(self, m_logger, m_apply_state_PK, m_revert_state_PK):
        tx = MessageTransaction.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_apply_state_changes(self, m_logger, m_apply_state_PK, m_revert_state_PK):
        tx = MessageTransaction.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([tx.txhash], addresses_state[self.alice.address].transaction_hashes)

        m_apply_state_PK.assert_called_once()
    def test_validate_tx(self, m_logger, m_apply_state_PK, m_revert_state_PK):
        tx = MessageTransaction.create(**self.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()
    def test_revert_state_changes(self, m_logger, m_apply_state_PK, m_revert_state_PK):
        tx = MessageTransaction.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)
        self.assertEqual([], addresses_state[self.alice.address].transaction_hashes)

        m_revert_state_PK.assert_called_once()
Example #11
0
    def test_validate_slave_signing_xmss_state_has_no_slave_permissions_in_state(
            self, m_logger):
        bob = get_bob_xmss()
        # Let's say Alice is Bob's master.
        self.params["master_addr"] = self.alice.address
        self.params["xmss_pk"] = bob.pk

        # We need to add extra data to the mock AddressState.
        self.m_addr_state.slave_pks_access_type = {}
        tx = MessageTransaction.create(**self.params)
        tx.sign(self.alice)
        result = tx.validate_slave(self.m_addr_state,
                                   self.m_addr_from_pk_state)
        self.assertFalse(result)
Example #12
0
    def relay_message_txn(self, message: 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 = MessageTransaction.create(
            message_hash=message.encode(),
            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)
Example #13
0
def tx_message(ctx, src, master, addr_to, message, fee, ots_key_index):
    """
    Message Transaction
    """
    try:
        _, 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)

        message = message.encode()
        if addr_to:
            addr_to = parse_qaddress(addr_to, False)
        else:
            addr_to = None

        master_addr = None
        if master:
            master_addr = parse_qaddress(master)
        fee_shor = _quanta_to_shor(fee)
    except Exception as e:
        click.echo("Error validating arguments: {}".format(e))
        quit(1)

    try:
        stub = ctx.obj.get_stub_public_api()
        tx = MessageTransaction.create(message_hash=message,
                                       addr_to=addr_to,
                                       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)
    except Exception as e:
        print("Error {}".format(str(e)))
Example #14
0
    def relay_message_txn_by_slave(self, message: 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 = MessageTransaction.create(
            message_hash=message.encode(),
            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)
Example #15
0
    def test_validate_extended(self, m_validate_slave, m_logger):
        """
        Message.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. addr_from ots_key reuse
        """
        m_addr_from_state = Mock(autospec=AddressState, name='addr_from State', balance=100)

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

        tx = MessageTransaction.create(**self.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.MessageTransaction.MessageTransaction.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)

        # 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_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)
Example #16
0
 def test_create(self, m_logger):
     tx = MessageTransaction.create(message_hash=b'Test Message',
                                    fee=1,
                                    xmss_pk=self.alice.pk)
     self.assertTrue(tx)
Example #17
0
 def test_set_affected_address(self, m_logger):
     result = set()
     tx = MessageTransaction.create(**self.params)
     tx.set_affected_address(result)
     self.assertEqual(1, len(result))