Esempio n. 1
0
    def test_revert_coinbase_txn(self, m_logger):
        """
        Alice earned some coins. Undo this.
        """
        tx = CoinBase.create(config.dev, self.amount, self.alice.address, self.mock_blockheader.block_number)
        addresses_state = {
            config.dev.coinbase_address: OptimizedAddressState.get_default(config.dev.coinbase_address),
            self.alice.address: OptimizedAddressState.get_default(self.alice.address),
        }
        addresses_state[config.dev.coinbase_address].pbdata.balance = 1000000

        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=self.mock_blockheader.block_number,
                                         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(1000000, addresses_state[config.dev.coinbase_address].balance)

        storage_key = state_container.paginated_tx_hash.generate_key(config.dev.coinbase_address, 1)
        self.assertEqual([], state_container.paginated_tx_hash.key_value[storage_key])
        self.assertEqual(0, addresses_state[self.alice.address].balance)

        storage_key = state_container.paginated_tx_hash.generate_key(config.dev.coinbase_address, 1)
        self.assertEqual([], state_container.paginated_tx_hash.key_value[storage_key])
Esempio n. 2
0
    def setUp(self):
        with set_xrd_dir('no_data'):
            self.state = State()

        self.alice = get_alice_xmss()
        self.bob = get_bob_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.bob.address:
            OptimizedAddressState.get_default(self.bob.address)
        }

        self.params = {
            "token_txhash": b'I declare the TEST token',
            "addrs_to": [self.bob.address],
            "amounts": [100],
            "fee": 1,
            "xmss_pk": self.alice.pk
        }

        self.unused_chain_manager_mock = Mock(autospec=ChainManager,
                                              name='unused ChainManager')
Esempio n. 3
0
    def test_apply_multi_sig_create_txn2(self):
        """
        Features Tested
        - Multi Sig Create txn with duplicate signatories

        Expectation
        - It should result into custom validation error throwing ValueError exception
        :return:
        """
        addresses_state = {
            self.alice.address:
            OptimizedAddressState.get_default(self.alice.address),
            self.bob.address:
            OptimizedAddressState.get_default(self.bob.address),
            self.random.address:
            OptimizedAddressState.get_default(self.random.address),
            self.random_signer.address:
            OptimizedAddressState.get_default(self.random_signer.address),
        }
        addresses_state[self.random_signer.address].pbdata.balance = 200
        modified_signatories = list(self.signatories)
        modified_weights = list(self.weights)

        # Appending bob as signatory second time
        modified_signatories.append(self.bob.address)
        modified_weights.append(2)

        tx = None
        with self.assertRaises(ValueError):
            tx = MultiSigCreate.create(modified_signatories, modified_weights,
                                       self.threshold, 1,
                                       self.random_signer.pk)
        self.assertIsNone(tx)
    def setUp(self):
        with set_xrd_dir('no_data'):
            self.state = State()

        self.alice = get_alice_xmss()
        self.bob = get_bob_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.bob.address:
            OptimizedAddressState.get_default(self.bob.address)
        }

        self.params = {
            "symbol": b'xrd',
            "name": b'Quantum Resistant Ledger',
            "owner": self.alice.address,
            "decimals": 15,
            "initial_balances": [],
            "fee": 1,
            "xmss_pk": self.alice.pk
        }

        self.unused_chain_manager_mock = Mock(autospec=ChainManager,
                                              name='unused ChainManager')
Esempio n. 5
0
    def test_apply(self):
        multi_sig_address = MultiSigAddressState.generate_multi_sig_address(
            b'')
        multi_sig_address_state = MultiSigAddressState.create(
            creation_tx_hash=b'',
            balance=100,
            signatories=[self.alice.address, self.bob.address],
            weights=[4, 6],
            threshold=5,
            transaction_hash_count=0)
        alice_address_state = OptimizedAddressState.get_default(
            self.alice.address)
        alice_address_state.pbdata.balance = 5
        bob_address_state = OptimizedAddressState.get_default(self.bob.address)
        addresses_state = {
            self.alice.address: alice_address_state,
            self.bob.address: bob_address_state,
            multi_sig_address: multi_sig_address_state,
        }

        tx = MultiSigSpend.create(multi_sig_address=multi_sig_address,
                                  addrs_to=[self.bob.address],
                                  amounts=[100],
                                  expiry_block_number=15000,
                                  fee=5,
                                  xmss_pk=self.alice.pk)
        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=self.state._db,
                                         batch=None)

        self.assertFalse(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.alice.address, tx.ots_key))

        tx.apply(self.state, state_container)

        self.assertTrue(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.alice.address, tx.ots_key))
        self.assertIn(tx.txhash, state_container.votes_stats)
        vote_stats = state_container.votes_stats[tx.txhash]
        self.assertEqual(vote_stats.shared_key, tx.txhash)
        self.assertEqual(vote_stats.total_weight, 0)
        self.assertEqual(vote_stats.signatories,
                         multi_sig_address_state.signatories)
Esempio n. 6
0
    def test_validate_all(self):
        """
        TODO: Check by signing txn from a non signatory address
        """
        multi_sig_address = MultiSigAddressState.generate_multi_sig_address(
            b'')
        tx = MultiSigSpend.create(multi_sig_address=multi_sig_address,
                                  addrs_to=[self.bob.address],
                                  amounts=[100],
                                  expiry_block_number=15000,
                                  fee=5,
                                  xmss_pk=self.random.pk,
                                  master_addr=self.alice.address)
        tx.sign(self.random)
        tx._data.nonce = 1
        alice_address_state = OptimizedAddressState.get_default(
            address=self.alice.address)
        alice_address_state.pbdata.balance = 5
        random_address_state = OptimizedAddressState.get_default(
            address=self.random.address)
        multi_sig_address_state = MultiSigAddressState.create(
            creation_tx_hash=b'',
            balance=100,
            signatories=[self.alice.address, self.bob.address],
            weights=[4, 6],
            threshold=5,
            transaction_hash_count=0)
        addresses_state = {
            self.alice.address: alice_address_state,
            self.random.address: random_address_state,
            multi_sig_address: multi_sig_address_state,
        }
        slaves = Indexer(b'slave', None)
        slaves.data[(self.alice.address,
                     self.random.pk)] = SlaveMetadata(access_type=0)

        state_container = StateContainer(addresses_state=addresses_state,
                                         tokens=Indexer(b'token', None),
                                         slaves=slaves,
                                         lattice_pk=Indexer(
                                             b'lattice_pk', None),
                                         multi_sig_spend_txs=dict(),
                                         votes_stats=dict(),
                                         block_number=10,
                                         total_coin_supply=100,
                                         current_dev_config=config.dev,
                                         write_access=False,
                                         my_db=self.state._db,
                                         batch=None)

        result = tx.validate_all(state_container)
        self.assertTrue(result)

        tx._data.nonce = 2
        result = tx.validate_all(state_container)
        self.assertFalse(result)  # False as nonce is invalid
    def test_revert_transfer_txn(self, m_logger):
        """
        Alice has sent 100 coins to Bob, using 1 as Transaction fee. Now we need to undo this.
        """
        self.tx.sign(self.alice)
        ots_key = self.alice.ots_index - 1

        addresses_state = {
            self.alice.address:
            OptimizedAddressState.get_default(self.alice.address),
            self.bob.address:
            OptimizedAddressState.get_default(self.bob.address)
        }
        addresses_state[self.alice.address].pbdata.balance = 200
        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)
        state_container.paginated_bitfield.set_ots_key(addresses_state,
                                                       self.alice.address,
                                                       ots_key)
        state_container.paginated_bitfield.put_addresses_bitfield(None)

        self.assertTrue(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.alice.address, ots_key))
        self.tx.apply(self.state, state_container)
        self.tx.revert(self.state, state_container)
        self.assertFalse(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.alice.address, ots_key))
        self.assertEqual(0, addresses_state[self.alice.address].nonce)

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

        storage_key = state_container.paginated_tx_hash.generate_key(
            self.alice.address, 1)
        self.assertEqual(
            [], state_container.paginated_tx_hash.key_value[storage_key])

        storage_key = state_container.paginated_tx_hash.generate_key(
            self.bob.address, 1)
        self.assertEqual(
            [], state_container.paginated_tx_hash.key_value[storage_key])
Esempio n. 8
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_for_PK_master_slave_XMSS(self, m_logger):
        addresses_state = {
            self.alice.address:
            OptimizedAddressState.get_default(self.alice.address),
            self.slave.address:
            OptimizedAddressState.get_default(self.slave.address)
        }
        addresses_state[self.alice.address].pbdata.balance = 101
        addresses_state[self.slave.address].pbdata.nonce = 1

        tx = TransferTransaction.create(addrs_to=[self.bob.address],
                                        amounts=[100],
                                        message_data=None,
                                        fee=1,
                                        xmss_pk=self.slave.pk,
                                        master_addr=self.alice.address)
        tx.sign(self.slave)
        ots_key = self.slave.ots_index - 1
        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)
        state_container.paginated_bitfield.set_ots_key(addresses_state,
                                                       self.slave.address,
                                                       ots_key)
        state_container.paginated_bitfield.put_addresses_bitfield(None)

        self.assertTrue(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.slave.address, ots_key))
        self.assertFalse(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.alice.address, self.alice.ots_index))
        tx._apply_state_changes_for_PK(state_container)
        tx._revert_state_changes_for_PK(state_container)
        self.assertFalse(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.slave.address, ots_key))
        self.assertFalse(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.alice.address, self.alice.ots_index))
Esempio n. 10
0
    def test_apply_state_changes_for_PK_master_slave_XMSS(self, m_logger):
        """
        If the TX was signed by a slave XMSS, the slave XMSS's AddressState should be updated (not the master's).
        :return:
        """
        tx = TransferTransaction.create(addrs_to=[self.bob.address],
                                        amounts=[100],
                                        message_data=None,
                                        fee=1,
                                        xmss_pk=self.slave.pk,
                                        master_addr=self.alice.address)
        addresses_state = {
            self.alice.address:
            OptimizedAddressState.get_default(self.alice.address),
            self.slave.address:
            OptimizedAddressState.get_default(self.slave.address)
        }
        tx.sign(self.slave)
        ots_key = self.slave.ots_index - 1
        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)

        self.assertFalse(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.slave.address, ots_key))
        self.assertFalse(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.alice.address, self.alice.ots_index))
        tx._apply_state_changes_for_PK(state_container)
        self.assertTrue(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.slave.address, ots_key))
        self.assertFalse(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.alice.address, self.alice.ots_index))

        self.assertEqual(1, addresses_state[self.slave.address].nonce)
        self.assertEqual(0, addresses_state[self.alice.address].nonce)
Esempio n. 11
0
    def test_revert_transfer_txn_tx_sends_to_self(self, m_logger):
        """
        Alice sent coins to herself, but she still lost the Transaction fee. Undo this.
        """
        addresses_state = {
            self.alice.address:
            OptimizedAddressState.get_default(self.alice.address),
            self.bob.address:
            OptimizedAddressState.get_default(self.bob.address)
        }
        addresses_state[self.alice.address].pbdata.balance = 200

        tx = TransferTransaction.create(addrs_to=[self.alice.address],
                                        amounts=[100],
                                        message_data=None,
                                        fee=1,
                                        xmss_pk=self.alice.pk)
        tx.sign(self.alice)
        ots_key = self.alice.ots_index - 1
        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)
        state_container.paginated_bitfield.set_ots_key(addresses_state,
                                                       self.alice.address,
                                                       ots_key)
        state_container.paginated_bitfield.put_addresses_bitfield(None)

        self.assertTrue(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.alice.address, ots_key))
        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, ots_key))

        self.assertEqual(200, addresses_state[self.alice.address].balance)
        self.assertEqual(0, addresses_state[self.bob.address].balance)
Esempio n. 12
0
    def test_set_ots_key2(self, mock_ots_bitfield_size,
                          mock_ots_tracking_per_page):
        """
        Randomly using OTS key
        :return:
        """
        with set_xrd_dir('no_data'):
            state = State()
            mock_ots_bitfield_size.return_value = ceil(
                config.dev.ots_tracking_per_page / 8)

            alice_xmss = get_alice_xmss(12)
            address = alice_xmss.address
            address_state = OptimizedAddressState.get_default(address)
            addresses_state = {address: address_state}
            paginated_bitfield = PaginatedBitfield(True, state._db)
            paginated_bitfield.update_used_page_in_address_state(
                address, addresses_state, 1)
            self.assertEqual(address_state.ots_bitfield_used_page, 0)

            ots_indexes = list(range(0, 2**alice_xmss.height))
            random.shuffle(ots_indexes)
            for i in ots_indexes:
                paginated_bitfield.set_ots_key(addresses_state, address, i)
                if i == ots_indexes[-1]:
                    self.assertEqual(address_state.ots_bitfield_used_page, 4)

            self.assertEqual(address_state.ots_bitfield_used_page, 4)
Esempio n. 13
0
    def test_sync_state_change_synced(self):
        chain_manager = Mock()
        chain_manager.height = 0
        chain_manager.get_block = MagicMock(return_value=GenesisBlock())
        chain_manager.last_block = GenesisBlock()
        chain_manager.tx_pool = Mock()
        chain_manager.tx_pool.transaction_pool = []
        chain_manager.tx_pool.transactions = chain_manager.tx_pool.transaction_pool

        get_block_metadata_response = Mock()
        get_block_metadata_response.block_difficulty = StringToUInt256('2')
        chain_manager.get_block_metadata = MagicMock(
            return_value=get_block_metadata_response)

        alice_xmss = get_alice_xmss()
        chain_manager._state.get_address_state = MagicMock(
            return_value=OptimizedAddressState.get_default(alice_xmss.address))
        chain_manager._state.get_measurement = MagicMock(return_value=60)

        p2p_factory = Mock()
        sync_state = Mock()
        time_provider = Mock()
        # Setting mining enabled False, when update_note_state set to synced,
        # starts miner which is not exited properly by unit test
        with set_mining_enabled(False):
            node = POW(chain_manager=chain_manager,
                       p2p_factory=p2p_factory,
                       sync_state=sync_state,
                       time_provider=time_provider,
                       mining_address=get_random_xmss().address,
                       mining_thread_count=0)

            self.assertIsNotNone(node)
            node.update_node_state(ESyncState.synced)
Esempio n. 14
0
    def test_insert(self):
        with set_xrd_dir('no_data'):
            state = State()
            p = PaginatedData(b'p_tx_hash', True, state._db)

            p.insert(OptimizedAddressState.get_default(b'a'), b'10')
            self.assertEqual(p.get_value(b'a', 0), [b'10'])
Esempio n. 15
0
    def test_revert_paginated_data2(self, mock_dev_config):
        with set_xrd_dir('no_data'):
            state = State()
            p = PaginatedData(b'p_tx_hash', True, state._db)
            alice_address_state = OptimizedAddressState.get_default(
                address=self.alice.address)

            for i in range(0, 25):
                p.insert(
                    alice_address_state, b'p_tx_hash_' +
                    i.to_bytes(8, byteorder='big', signed=False))

            p.put_paginated_data(None)

            full_hash = []
            for i in range(0, (25 // config.dev.data_per_page) + 1):
                data = p.get_paginated_data(
                    self.alice.address, (i + 1) * config.dev.data_per_page - 1)
                full_hash.extend(data)

            for tx_hash in full_hash[-1::-1]:
                p.remove(alice_address_state, tx_hash)
            p.put_paginated_data(None)

            self.assertEqual(
                alice_address_state.get_counter_by_name(b'p_tx_hash'), 0)

            self.assertEqual(
                len(p.get_paginated_data(alice_address_state.address, 22)), 0)

            self.assertEqual(
                len(p.get_paginated_data(alice_address_state.address, 12)), 0)

            self.assertEqual(
                len(p.get_paginated_data(alice_address_state.address, 2)), 0)
Esempio n. 16
0
    def test_get_paginated_data(self, mock_dev_config):
        with set_xrd_dir('no_data'):
            state = State()
            p = PaginatedData(b'p_tx_hash', True, state._db)
            alice_address_state = OptimizedAddressState.get_default(
                address=self.alice.address)

            total_hashes = 25
            expected_full_hash = []
            for i in range(0, total_hashes):
                tx_hash = b'p_tx_hash_' + i.to_bytes(
                    8, byteorder='big', signed=False)
                p.insert(alice_address_state, tx_hash)
                expected_full_hash.append(tx_hash)

            p.put_paginated_data(None)

            found_full_hash = []
            expected_data_count = [10, 10, 5]
            for i in range(0, (total_hashes // config.dev.data_per_page) + 1):
                data = p.get_paginated_data(
                    self.alice.address, (i + 1) * config.dev.data_per_page - 1)
                self.assertEqual(len(data), expected_data_count[i])
                found_full_hash.extend(data)

            self.assertEqual(expected_full_hash, found_full_hash)
    def test_update_used_page_in_address_state4(self, mock_ots_bitfield_size, mock_ots_tracking_per_page):
        mock_ots_bitfield_size.return_value = ceil(config.dev.ots_tracking_per_page / 8)

        alice_xmss = get_alice_xmss(12)
        address = alice_xmss.address
        address_state = OptimizedAddressState.get_default(address)
        addresses_state = {address: address_state}
        paginated_bitfield = PaginatedBitfield(True, self.state._db)
        paginated_bitfield.update_used_page_in_address_state(address, addresses_state, 1)
        self.assertEqual(address_state.ots_bitfield_used_page, 0)

        for i in range(2048, 3072):
            paginated_bitfield.set_ots_key(addresses_state, address, i)
            self.assertEqual(address_state.ots_bitfield_used_page, 0)

        for i in range(1024, 2048):
            paginated_bitfield.set_ots_key(addresses_state, address, i)
            self.assertEqual(address_state.ots_bitfield_used_page, 0)

        for i in range(0, 1024):
            paginated_bitfield.set_ots_key(addresses_state, address, i)
            if i + 1 == 1024:
                self.assertEqual(address_state.ots_bitfield_used_page, 3)

        for i in range(3072, 2 ** alice_xmss.height):
            paginated_bitfield.set_ots_key(addresses_state, address, i)
            if i + 1 == 2 ** alice_xmss.height:
                self.assertEqual(address_state.ots_bitfield_used_page, 4)
            else:
                self.assertEqual(address_state.ots_bitfield_used_page, 3)

        self.assertEqual(address_state.ots_bitfield_used_page, 4)
    def test_update_used_page_in_address_state(self):
        alice_xmss = get_alice_xmss(4)
        address = alice_xmss.address
        address_state = OptimizedAddressState.get_default(address)
        addresses_state = {address: address_state}
        paginated_bitfield = PaginatedBitfield(True, self.state._db)
        key = paginated_bitfield.generate_bitfield_key(address, 1)
        paginated_bitfield.update_used_page_in_address_state(address, addresses_state, 1)
        self.assertEqual(address_state.ots_bitfield_used_page, 0)

        for i in range(0, 16):
            paginated_bitfield.set_ots_key(addresses_state, address, i)
            if i != 15:
                self.assertEqual(address_state.ots_bitfield_used_page, 0)
            else:
                self.assertEqual(address_state.ots_bitfield_used_page, 1)

        for i in range(0, 16):
            ots_bitfield = paginated_bitfield.key_value[key]
            ots_key_index = i % config.dev.ots_tracking_per_page
            offset = ots_key_index >> 3
            relative = ots_key_index % 8
            bitfield = bytearray(ots_bitfield[offset])
            self.assertEqual(bytes([bitfield[0] >> relative & 1]), b'\x01')

        self.assertEqual(address_state.ots_bitfield_used_page, 1)
Esempio n. 19
0
    def test_ots_key_reuse(self, mock_ots_bitfield_size,
                           mock_ots_tracking_per_page):
        """
        Randomly using OTS key
        :return:
        """
        with set_xrd_dir('no_data'):
            state = State()

            mock_ots_bitfield_size.return_value = ceil(
                config.dev.ots_tracking_per_page / 8)
            paginated_bitfield = PaginatedBitfield(True, state._db)

            alice_xmss = get_alice_xmss(12)
            address = alice_xmss.address
            address_state = OptimizedAddressState.get_default(address)
            addresses_state = {address: address_state}
            bitfield_data = paginated_bitfield.get_paginated_data(address, 1)
            self.assertFalse(paginated_bitfield.ots_key_reuse(
                bitfield_data, 0))

            paginated_bitfield.set_ots_key(addresses_state, address, 0)
            bitfield_data = paginated_bitfield.get_paginated_data(address, 1)
            # False, as bitfield has been set but has not been written to state.
            self.assertFalse(paginated_bitfield.ots_key_reuse(
                bitfield_data, 0))

            # Writing bitfield to the state.
            paginated_bitfield.put_addresses_bitfield(None)
            bitfield_data = paginated_bitfield.get_paginated_data(address, 1)
            self.assertTrue(paginated_bitfield.ots_key_reuse(bitfield_data, 0))
Esempio n. 20
0
    def test_apply_transfer_txn_tx_sends_to_self(self, m_logger):
        """
        If you send coins to yourself, you should only lose the fee for the Transaction.
        """
        addresses_state = {
            self.alice.address:
            OptimizedAddressState.get_default(self.alice.address),
            self.bob.address:
            OptimizedAddressState.get_default(self.bob.address),
            self.slave.address:
            OptimizedAddressState.get_default(self.slave.address)
        }
        addresses_state[self.alice.address].pbdata.balance = 200

        tx = TransferTransaction.create(addrs_to=[self.alice.address],
                                        amounts=[100],
                                        message_data=None,
                                        fee=1,
                                        xmss_pk=self.alice.pk)
        tx.sign(self.alice)
        ots_key = self.alice.ots_index - 1
        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)
        self.assertFalse(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.alice.address, ots_key))
        tx.apply(self.state, state_container)
        self.assertTrue(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.alice.address, ots_key))

        self.assertEqual(199, addresses_state[self.alice.address].balance)
        storage_key = state_container.paginated_tx_hash.generate_key(
            self.alice.address, 1)
        self.assertIn(tx.txhash,
                      state_container.paginated_tx_hash.key_value[storage_key])
Esempio n. 21
0
    def test_apply_transfer_txn_multi_send(self, m_logger):
        """
        Test that apply_state_changes() also works with multiple recipients.
        """
        addresses_state = {
            self.alice.address:
            OptimizedAddressState.get_default(self.alice.address),
            self.bob.address:
            OptimizedAddressState.get_default(self.bob.address),
            self.slave.address:
            OptimizedAddressState.get_default(self.slave.address)
        }
        addresses_state[self.alice.address].pbdata.balance = 200

        tx_multisend = TransferTransaction.create(
            addrs_to=[self.bob.address, self.slave.address],
            amounts=[20, 20],
            message_data=None,
            fee=1,
            xmss_pk=self.alice.pk)
        tx_multisend.sign(self.alice)
        ots_key = self.alice.ots_index - 1
        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)
        self.assertFalse(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.alice.address, ots_key))
        tx_multisend.apply(self.state, state_container)
        self.assertTrue(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.alice.address, ots_key))

        self.assertEqual(159, addresses_state[self.alice.address].balance)
        self.assertEqual(20, addresses_state[self.bob.address].balance)
        self.assertEqual(20, addresses_state[self.slave.address].balance)
Esempio n. 22
0
    def test_validate_all(self):
        tx = MultiSigCreate.create(signatories=self.signatories,
                                   weights=self.weights,
                                   threshold=self.threshold,
                                   fee=5,
                                   xmss_pk=self.random.pk,
                                   master_addr=self.alice.address)
        tx.sign(self.random)
        tx.pbdata.nonce = 1

        alice_address_state = OptimizedAddressState.get_default(
            address=self.alice.address)
        alice_address_state.pbdata.balance = 5
        random_address_state = OptimizedAddressState.get_default(
            address=self.random.address)

        addresses_state = {
            self.alice.address: alice_address_state,
            self.random.address: random_address_state,
        }
        slaves = Indexer(b'slave', None)
        slaves.data[(self.alice.address,
                     self.random.pk)] = SlaveMetadata(access_type=0)
        state_container = StateContainer(addresses_state=addresses_state,
                                         tokens=Indexer(b'token', None),
                                         slaves=slaves,
                                         lattice_pk=Indexer(
                                             b'lattice_pk', None),
                                         multi_sig_spend_txs=dict(),
                                         votes_stats=dict(),
                                         block_number=10,
                                         total_coin_supply=100,
                                         current_dev_config=config.dev,
                                         write_access=False,
                                         my_db=self.state._db,
                                         batch=None)

        result = tx.validate_all(state_container)
        self.assertTrue(result)

        tx.pbdata.nonce = 2
        result = tx.validate_all(state_container)
        self.assertFalse(result)  # False as nonce is invalid
Esempio n. 23
0
    def test_put_paginated_data(self, mock_dev_config):
        with set_xrd_dir('no_data'):
            state = State()
            p = PaginatedData(b'p_tx_hash', True, state._db)
            alice_address_state = OptimizedAddressState.get_default(
                address=self.alice.address)

            for i in range(0, 10):
                p.insert(
                    alice_address_state, b'p_tx_hash_' +
                    i.to_bytes(8, byteorder='big', signed=False))
                self.assertEqual(
                    alice_address_state.get_counter_by_name(p.name), i + 1)

            p.put_paginated_data(None)
            self.assertEqual(alice_address_state.get_counter_by_name(p.name),
                             10)

            for i in range(10, 25):
                p.insert(
                    alice_address_state, b'p_tx_hash_' +
                    i.to_bytes(8, byteorder='big', signed=False))
                self.assertEqual(
                    alice_address_state.get_counter_by_name(p.name), i + 1)

            p.put_paginated_data(None)
            self.assertEqual(alice_address_state.get_counter_by_name(p.name),
                             25)
            self.assertEqual(len(p.key_value), 0)

            pages_data = []
            for i in range(0, (25 // config.dev.data_per_page) + 1):
                data = p.get_paginated_data(
                    self.alice.address, (i + 1) * config.dev.data_per_page - 1)
                pages_data.append(data)

            self.assertEqual(len(pages_data), 3)

            self.assertEqual(len(pages_data[0]), 10)
            for i in range(0, 10):
                self.assertEqual(
                    pages_data[0][i], b'p_tx_hash_' +
                    i.to_bytes(8, byteorder='big', signed=False))

            self.assertEqual(len(pages_data[1]), 10)
            for i in range(10, 20):
                self.assertEqual(
                    pages_data[1][i - 10], b'p_tx_hash_' +
                    i.to_bytes(8, byteorder='big', signed=False))

            self.assertEqual(len(pages_data[2]), 5)
            for i in range(20, 25):
                self.assertEqual(
                    pages_data[2][i - 20], b'p_tx_hash_' +
                    i.to_bytes(8, byteorder='big', signed=False))
Esempio n. 24
0
    def test_revert_transfer_token_txn_multi_send(self):
        """
        Alice has 1100 tokens and 100 xrd, 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)
Esempio n. 25
0
    def test_apply_transfer_txn(self, m_logger):
        """
        apply_state_changes() is the part that actually updates everybody's balances.
        Then it forwards the addresses_state to _apply_state_changes_for_PK(), which updates everybody's addresses's
        nonce, OTS key index, and associated TX hashes
        If there is no AddressState for a particular Address, nothing is done.
        """
        self.tx.sign(self.alice)
        ots_key = self.alice.ots_index - 1
        addresses_state = {
            self.alice.address:
            OptimizedAddressState.get_default(self.alice.address),
            self.bob.address:
            OptimizedAddressState.get_default(self.bob.address),
            self.slave.address:
            OptimizedAddressState.get_default(self.slave.address)
        }
        addresses_state[self.alice.address].pbdata.balance = 200
        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)
        self.assertFalse(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.alice.address, ots_key))
        self.tx.apply(self.state, state_container)
        self.assertTrue(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.alice.address, ots_key))

        # Now Alice should have 99 coins left (200 - 100 - 1) and Bob should have 100 coins.
        self.assertEqual(99, addresses_state[self.alice.address].balance)
        self.assertEqual(100, addresses_state[self.bob.address].balance)
Esempio n. 26
0
 def test_put_addresses_state(self):
     with set_xrd_dir('no_data'):
         with State() as state:
             alice_xmss = get_alice_xmss()
             alice_state = OptimizedAddressState.get_default(
                 alice_xmss.address)
             addresses_state = {
                 alice_state.address: alice_state,
                 b'test1': OptimizedAddressState.get_default(b'test1')
             }
             AddressState.put_addresses_state(state, addresses_state, None)
             alice_state2 = OptimizedAddressState.get_optimized_address_state(
                 state, alice_xmss.address)
             self.assertEqual(alice_state.serialize(),
                              alice_state2.serialize())
             test_state = OptimizedAddressState.get_optimized_address_state(
                 state, b'test1')
             self.assertEqual(
                 test_state.serialize(),
                 OptimizedAddressState.get_default(b'test1').serialize())
Esempio n. 27
0
    def test_get_mini_transactions_by_address(self, mock_get_tx_metadata,
                                              mock_get_optimized_address_state,
                                              mock_get_paginated_data):
        """
        xrdNode.get_transactions_by_address() returns all the changes in balance caused by a transaction.
        """
        get_tx_metadata = GetTXMetadata()

        xmss = get_alice_xmss()
        xmss2 = get_random_xmss()
        addr_state = OptimizedAddressState.get_default(xmss.address)
        addr_state.pbdata.balance = 100
        addr_state.pbdata.transaction_hash_count = 3
        mock_get_optimized_address_state.return_value = addr_state

        tx1 = CoinBase.create(config.dev, 100, xmss.address, 5)
        get_tx_metadata.register_tx_metadata(tx1, 1)

        tx2 = TransferTransaction.create(addrs_to=[xmss2.address],
                                         amounts=[10],
                                         message_data=None,
                                         fee=1,
                                         xmss_pk=xmss.pk)
        tx2.sign(xmss)
        get_tx_metadata.register_tx_metadata(tx2, 1)

        tx3 = TransferTransaction.create(addrs_to=[xmss.address],
                                         amounts=[100],
                                         message_data=None,
                                         fee=1,
                                         xmss_pk=xmss2.pk)
        tx3.sign(xmss)
        get_tx_metadata.register_tx_metadata(tx3, 2)

        mock_get_paginated_data.return_value = [
            tx1.txhash, tx2.txhash, tx3.txhash
        ]
        mock_get_tx_metadata.side_effect = get_tx_metadata.get_tx_metadata
        response = self.xrdnode.get_mini_transactions_by_address(
            alice.address, 3, 1)
        result, balance = response.mini_transactions, response.balance
        self.assertEqual(len(result), 3)

        self.assertEqual(result[0].amount, 100)
        self.assertEqual(result[0].out, False)

        self.assertEqual(result[1].amount, 11)
        self.assertEqual(result[1].out, True)

        self.assertEqual(result[2].amount, 100)
        self.assertEqual(result[2].out, False)

        self.assertEqual(balance, 100)
Esempio n. 28
0
    def test_validate_extended(self, m_logger):
        """
        CoinBase validate_extended() checks for
        1. valid coinbase address (the coinbase address must be config.dev.coinbase_address)
        2. valid addr_to
        then calls _validate_custom()
        """
        tx = CoinBase.create(config.dev, self.amount, self.alice.address, self.mock_blockheader.block_number)
        tx._data.master_addr = self.alice.address

        addresses_state = {
            config.dev.coinbase_address: OptimizedAddressState.get_default(config.dev.coinbase_address),
            self.alice.address: OptimizedAddressState.get_default(self.alice.address),
        }
        addresses_state[config.dev.coinbase_address].pbdata.balance = 1000000

        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=self.mock_blockheader.block_number,
                                         total_coin_supply=100,
                                         current_dev_config=config.dev,
                                         write_access=True,
                                         my_db=self.state._db,
                                         batch=None)

        result = tx._validate_extended(state_container)
        self.assertFalse(result)

        tx._data.master_addr = config.dev.coinbase_address
        with patch('xrd.core.txs.CoinBase.CoinBase.addr_to', new_callable=PropertyMock) as m_addr_to:
            m_addr_to.return_value = b'Fake Address'
            result = tx._validate_extended(state_container)
            self.assertFalse(result)

        result = tx._validate_extended(state_container)
        self.assertTrue(result)
Esempio n. 29
0
    def setUp(self):
        with set_xrd_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')
Esempio n. 30
0
    def test_unset_ots_key3(self, mock_ots_bitfield_size,
                            mock_ots_tracking_per_page):
        """
        Features Tested
        - Sequentially marking OTS indexes as used
        - Sequentially marking OTS indexes as unused
        - ots_bitfield_used_page value with each OTS index being used

        Expectation
        - The ots_bitfield_used_page must increase by 1 for every sequential 1024 (ots_tracking_per_page) ots indexes
          marked as used

        :param mock_ots_bitfield_size:
        :param mock_ots_tracking_per_page:
        :return:
        """
        with set_xrd_dir('no_data'):
            state = State()
            mock_ots_bitfield_size.return_value = ceil(
                config.dev.ots_tracking_per_page / 8)

            alice_xmss = get_alice_xmss(12)
            address = alice_xmss.address
            address_state = OptimizedAddressState.get_default(address)
            addresses_state = {address: address_state}
            paginated_bitfield = PaginatedBitfield(True, state._db)
            paginated_bitfield.update_used_page_in_address_state(
                address, addresses_state, 1)
            self.assertEqual(address_state.ots_bitfield_used_page, 0)

            total_ots = 2**alice_xmss.height
            for i in range(0, total_ots + 1):
                paginated_bitfield.set_ots_key(addresses_state, address, i)
                self.assertEqual(address_state.ots_bitfield_used_page,
                                 (i + 1) // config.dev.ots_tracking_per_page)

            self.assertEqual(address_state.ots_bitfield_used_page,
                             total_ots // config.dev.ots_tracking_per_page)
            self.assertEqual(total_ots // config.dev.ots_tracking_per_page, 4)

            paginated_bitfield.unset_ots_key(addresses_state, address,
                                             total_ots - 1)
            self.assertEqual(address_state.ots_bitfield_used_page, 3)

            for i in range(total_ots - 2, -1, -1):
                paginated_bitfield.unset_ots_key(addresses_state, address, i)
                self.assertEqual(address_state.ots_bitfield_used_page,
                                 i // config.dev.ots_tracking_per_page)