예제 #1
0
    def __init__(self, *args, **kwargs):
        super(TestSimpleTransaction, self).__init__(*args, **kwargs)
        self.alice = get_alice_xmss()
        self.bob = get_bob_xmss()
        self.slave = get_slave_xmss()

        self.alice.set_ots_index(10)
        self.maxDiff = None
예제 #2
0
 def setUp(self):
     self.alice = get_alice_xmss()
     self.slave = get_slave_xmss()
     self.params = {
         "slave_pks": [self.slave.pk],
         "access_types": [0],
         "fee": 1,
         "xmss_pk": self.alice.pk
     }
    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)
예제 #4
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('xrd.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(
                'xrd.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 xrd Address'
        with self.assertRaises(ValueError):
            tx = TransferTokenTransaction.create(**params)

        params = self.default_params()
        params["addrs_to"] = [self.bob.address, b'Bad xrd address']
        params["amounts"] = [100, 200]
        with self.assertRaises(ValueError):
            tx = TransferTokenTransaction.create(**params)
    def test_apply_token_txn_signed_by_slave_xmss(self):
        """
        Alice creates a token, gives herself and Bob some tokens.
        But she uses a XMSS slave to sign it.
        """
        initial_balances = [qrl_pb2.AddressAmount(address=self.alice.address, amount=1000),
                            qrl_pb2.AddressAmount(address=self.bob.address, amount=2000)]
        slave = get_slave_xmss()
        self.params["initial_balances"] = initial_balances
        self.params["xmss_pk"] = slave.pk
        self.params["master_addr"] = self.alice.address
        tx = TokenTransaction.create(**self.params)
        tx.sign(slave)

        # Now that we have the Slave XMSS address, we should add it to AddressState so that apply_state_changes()
        # can do something with it
        addresses_state = dict(self.addresses_state)
        addresses_state[slave.address] = OptimizedAddressState.get_default(slave.address)
        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=1000,
                                         current_dev_config=config.dev,
                                         write_access=True,
                                         my_db=self.state._db,
                                         batch=None)
        tx.apply(self.state, state_container)

        self.assertEqual(addresses_state[self.alice.address].balance, 99)
        self.assertEqual(3, len(state_container.paginated_tx_hash.key_value))

        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([tx.txhash], state_container.paginated_tx_hash.key_value[storage_key])

        storage_key = state_container.paginated_tx_hash.generate_key(self.bob.address, 1)
        self.assertIn(storage_key, state_container.paginated_tx_hash.key_value)
        self.assertEqual([tx.txhash], state_container.paginated_tx_hash.key_value[storage_key])

        storage_key = state_container.paginated_tx_hash.generate_key(slave.address, 1)
        self.assertIn(storage_key, state_container.paginated_tx_hash.key_value)
        self.assertEqual([tx.txhash], state_container.paginated_tx_hash.key_value[storage_key])

        self.assertEqual(2, len(state_container.tokens.data))
        self.assertIn((self.bob.address, tx.txhash), state_container.tokens.data)
        self.assertEqual(1000, state_container.tokens.data[(self.alice.address, tx.txhash)].balance)
        self.assertEqual(2000, state_container.tokens.data[(self.bob.address, tx.txhash)].balance)

        self.assertTrue(state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(slave.address, 0))
        self.assertFalse(state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(self.alice.address, 0))
        self.assertFalse(state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(self.bob.address, 0))
예제 #6
0
    def __init__(self, *args, **kwargs):
        super(TestSimpleTransaction, self).__init__(*args, **kwargs)
        with set_qrl_dir('no_data'):
            self.state = State()

        self.alice = get_alice_xmss()
        self.bob = get_bob_xmss()
        self.slave = get_slave_xmss()

        self.alice.set_ots_index(10)
        self.maxDiff = None
 def setUp(self):
     self.alice = get_alice_xmss()
     self.slave = get_slave_xmss()
     self.params = {
         "slave_pks": [self.slave.pk],
         "access_types": [0],
         "fee": 1,
         "xmss_pk": self.alice.pk
     }
     self.unused_chain_manager_mock = Mock(autospec=ChainManager,
                                           name='unused ChainManager')
    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))
예제 #9
0
    def setUp(self):
        with set_xrd_dir('no_data'):
            self.state = State()
        self.chain_manager = ChainManager(self.state)
        self.alice = get_alice_xmss()
        self.bob = get_bob_xmss()
        self.slave = get_slave_xmss()

        self.tx1 = TransferTransaction.create(addrs_to=[self.bob.address],
                                              amounts=[10],
                                              message_data=None,
                                              fee=1,
                                              xmss_pk=self.alice.pk)
        self.tx2 = TransferTransaction.create(addrs_to=[self.bob.address],
                                              amounts=[10],
                                              message_data=None,
                                              fee=1,
                                              xmss_pk=self.slave.pk,
                                              master_addr=self.alice.address)
        self.tx1._data.nonce = 3
        self.tx2._data.nonce = 6
        self.tx1.sign(self.alice)
        self.tx2.sign(self.slave)

        self.block_attrs = {
            "dev_config": config.dev,
            "block_number": 5,
            "prev_headerhash": bytes(sha2_256(b'test')),
            "prev_timestamp": 10,
            "transactions": [self.tx1, self.tx2],
            "miner_address": self.alice.address,
            "seed_height": 0,
            "seed_hash": None,
        }
        self.coinbase_addrstate_attrs = OptimizedAddressState.get_default(
            config.dev.coinbase_address)
        self.coinbase_addrstate_attrs.update_balance(
            None,
            int(config.dev.coin_remaining_at_genesis *
                config.dev.shor_per_quanta))
        self.bob_addrstate_attrs = OptimizedAddressState.get_default(
            self.bob.address)
        self.bob_addrstate_attrs.update_balance(None, 20)
        self.alice_addrstate_attrs = OptimizedAddressState.get_default(
            self.alice.address)
        self.alice_addrstate_attrs.update_balance(None, 100)
        self.alice_addrstate_attrs.pbdata.nonce = 2
        self.slave_addrstate_attrs = OptimizedAddressState.get_default(
            self.slave.address)
        self.slave_addrstate_attrs.pbdata.nonce = 5
    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()
    def test_validate_tx(self):
        initial_balances = [qrl_pb2.AddressAmount(address=self.alice.address, amount=1000),
                            qrl_pb2.AddressAmount(address=self.bob.address, amount=1000)]
        slave = get_slave_xmss()
        self.params["initial_balances"] = initial_balances
        self.params["xmss_pk"] = slave.pk
        self.params["master_addr"] = self.alice.address
        tx = TokenTransaction.create(**self.params)
        tx.sign(slave)

        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()
예제 #12
0
    def test_affected_address(self, m_logger):
        tx = TokenTransaction.create(**self.params)
        # Default params should result in 2 affected addresses
        result = set()
        tx.set_affected_address(result)
        self.assertEqual(2, len(result))

        # If the slave is a recipient of tokens, he should be included too.
        slave = get_slave_xmss()
        result = set()
        self.initial_balances_valid.append(xrd_pb2.AddressAmount(address=slave.address, amount=1000))
        tx = TokenTransaction.create(symbol=b'xrd',
                                     name=b'Quantum Resistant Ledger',
                                     owner=self.alice.address,
                                     decimals=15,
                                     initial_balances=self.initial_balances_valid,
                                     fee=1,
                                     xmss_pk=self.alice.pk)
        tx.set_affected_address(result)
        self.assertEqual(3, len(result))
예제 #13
0
    def setUp(self):
        self.alice = get_alice_xmss()
        self.bob = get_bob_xmss()
        self.slave = get_slave_xmss()

        self.tx1 = TransferTransaction.create(addrs_to=[self.bob.address],
                                              amounts=[10],
                                              fee=1,
                                              xmss_pk=self.alice.pk)
        self.tx2 = TransferTransaction.create(addrs_to=[self.bob.address],
                                              amounts=[10],
                                              fee=1,
                                              xmss_pk=self.slave.pk,
                                              master_addr=self.alice.address)
        # self.tx1 = Mock(autospec=TransferTransaction, addrs_to=[self.bob.address], amounts=[10], fee=1,
        #                 xmss_pk=self.alice.pk)
        # self.tx2 = Mock(autospec=TransferTransaction, addrs_to=[self.bob.address], amounts=[10], fee=1,
        #                 xmss_pk=self.slave.pk, master_addr=self.alice.address)
        self.tx1._data.nonce = 3
        self.tx2._data.nonce = 6
        self.tx1.sign(self.alice)
        self.tx2.sign(self.slave)

        self.block_attrs = {
            "block_number": 5,
            "prev_headerhash": bytes(sha2_256(b'test')),
            "prev_timestamp": 10,
            "transactions": [self.tx1, self.tx2],
            "miner_address": self.alice.address
        }
        self.alice_addrstate_attrs = {
            'nonce': 2,
            'ots_key_reuse.return_value': False
        }
        self.slave_addrstate_attrs = {
            'nonce': 5,
            'ots_key_reuse.return_value': False
        }
    def setUp(self):
        with set_qrl_dir('no_data'):
            self.state = State()

        self.alice = get_alice_xmss()
        self.slave = get_slave_xmss()
        alice_address_state = OptimizedAddressState.get_default(
            self.alice.address)
        alice_address_state.pbdata.balance = 100
        self.addresses_state = {
            self.alice.address:
            alice_address_state,
            self.slave.address:
            OptimizedAddressState.get_default(self.slave.address)
        }

        self.params = {
            "slave_pks": [self.slave.pk],
            "access_types": [0],
            "fee": 1,
            "xmss_pk": self.alice.pk
        }
        self.unused_chain_manager_mock = Mock(autospec=ChainManager,
                                              name='unused ChainManager')
예제 #15
0
from qrl.core.txs.TransferTransaction import TransferTransaction
from qrl.core.p2p.p2pprotocol import P2PProtocol
from qrl.core.p2p.p2pPeerManager import P2PPeerManager
from qrl.core.p2p.p2pChainManager import P2PChainManager
from qrl.core.node import POW
from qrl.generated import qrl_pb2
from pyqrllib.pyqrllib import hstr2bin

from tests.misc.MockHelper.mock_get_tx_metadata import GetTXMetadata
from tests.core.test_State import gen_blocks
from tests.misc.helper import set_qrl_dir, get_alice_xmss, get_slave_xmss, replacement_getTime, get_random_xmss

logger.initialize_default()

alice = get_alice_xmss()
slave = get_slave_xmss()


@patch('qrl.core.misc.ntp.getTime', new=replacement_getTime)
class TestQRLNodeReal(TestCase):
    @patch('qrl.core.misc.ntp.getTime', new=replacement_getTime)
    def setUp(self):
        # You have to set_qrl_dir to an empty one, otherwise State will have some Transactions from disk
        with set_qrl_dir('no_data'):
            self.db_state = State()
            self.chainmanager = ChainManager(self.db_state)
            self.qrlnode = QRLNode(mining_address=b'')
            self.qrlnode.set_chain_manager(self.chainmanager)

    @patch('qrl.core.qrlnode.QRLNode.block_height',
           new_callable=PropertyMock,
예제 #16
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))