コード例 #1
0
    def test_apply_transfer_token_txn_multi_send(self):
        """
        Alice has 1000 tokens and 100 QRL, Bob and Slave have none. Alice sends some tokens to Bob and Slave.
        """
        slave = get_slave_xmss()
        params = self.params.copy()
        params["addrs_to"] = [self.bob.address, slave.address]
        params["amounts"] = [100, 100]

        tx = TransferTokenTransaction.create(**params)
        tx.sign(self.alice)
        addresses_state = dict(self.addresses_state)
        addresses_state[slave.address] = OptimizedAddressState.get_default(
            slave.address)
        tokens = Indexer(b'token', None)
        tokens.data[(self.alice.address,
                     tx.token_txhash)] = TokenBalance(balance=200)
        tokens.data[(self.bob.address,
                     tx.token_txhash)] = TokenBalance(balance=0)
        tokens.data[(slave.address, tx.token_txhash)] = TokenBalance(balance=0)
        state_container = StateContainer(addresses_state=addresses_state,
                                         tokens=tokens,
                                         slaves=Indexer(b'slave', None),
                                         lattice_pk=Indexer(
                                             b'lattice_pk', None),
                                         multi_sig_spend_txs=dict(),
                                         votes_stats=dict(),
                                         block_number=1,
                                         total_coin_supply=1000,
                                         current_dev_config=config.dev,
                                         write_access=True,
                                         my_db=self.state._db,
                                         batch=None)

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

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

        self.assertEqual(
            tokens.data[(self.alice.address, tx.token_txhash)].balance, 0)
        self.assertEqual(
            tokens.data[(self.bob.address, tx.token_txhash)].balance, 100)
        self.assertEqual(tokens.data[(slave.address, tx.token_txhash)].balance,
                         100)
コード例 #2
0
    def apply(self, state: State, state_container: StateContainer) -> bool:
        state_container.tokens.data[(
            self.addr_from, self.token_txhash)].balance -= self.total_amount
        decimals = state_container.tokens.data[(self.addr_from,
                                                self.token_txhash)].decimals
        address_state = state_container.addresses_state[self.addr_from]
        address_state.update_balance(state_container, self.fee, subtract=True)
        state_container.paginated_tx_hash.insert(address_state, self.txhash)

        for index in range(0, len(self.addrs_to)):
            addr_to = self.addrs_to[index]
            amount = self.amounts[index]
            address_state = state_container.addresses_state[addr_to]

            # If receiver doesn't have this token before, then initialize token balance data into state
            # before adding the new balance.
            if (addr_to, self.token_txhash) not in state_container.tokens.data:
                state_container.tokens.data[(
                    addr_to,
                    self.token_txhash)] = TokenBalance(balance=0,
                                                       decimals=decimals,
                                                       tx_hash=self.txhash,
                                                       delete=False)
                state_container.paginated_tokens_hash.insert(
                    address_state, self.token_txhash)

            state_container.tokens.data[(addr_to,
                                         self.token_txhash)].balance += amount

            if self.addr_from != addr_to:
                state_container.paginated_tx_hash.insert(
                    address_state, self.txhash)

        return self._apply_state_changes_for_PK(state_container)
コード例 #3
0
ファイル: TokenTransaction.py プロジェクト: zeta1999/QRL
    def apply(self, state: State, state_container: StateContainer) -> bool:
        addr_from_pk = bytes(QRLHelper.getAddress(self.PK))
        owner_processed = False
        addr_from_processed = False
        addr_from_pk_processed = False

        for initial_balance in self.initial_balances:
            if initial_balance.address == self.owner:
                owner_processed = True
            if initial_balance.address == self.addr_from:
                addr_from_processed = True
            if initial_balance.address == addr_from_pk:
                addr_from_pk_processed = True

            # If a QRL address has been mentioned multiple times in initial balance
            # then check if that address has already been initialized with some token
            # balance, if found, then add the new balance the already initialized balance
            if (initial_balance.address,
                    self.txhash) in state_container.tokens.data:
                state_container.tokens.data[(
                    initial_balance.address,
                    self.txhash)].balance += initial_balance.amount
            else:
                state_container.tokens.data[(
                    initial_balance.address, self.txhash)] = TokenBalance(
                        balance=initial_balance.amount,
                        decimals=self.decimals,
                        tx_hash=self.txhash,
                        delete=False)
            address_state = state_container.addresses_state[
                initial_balance.address]
            state_container.paginated_tx_hash.insert(address_state,
                                                     self.txhash)
            state_container.paginated_tokens_hash.insert(
                address_state, self.txhash)

        if not owner_processed:
            address_state = state_container.addresses_state[self.owner]
            state_container.paginated_tx_hash.insert(address_state,
                                                     self.txhash)

        address_state = state_container.addresses_state[self.addr_from]
        address_state.update_balance(state_container, self.fee, subtract=True)
        if not addr_from_processed and self.addr_from != self.owner:
            state_container.paginated_tx_hash.insert(address_state,
                                                     self.txhash)

        address_state = state_container.addresses_state[addr_from_pk]
        if self.addr_from != addr_from_pk and addr_from_pk != self.owner:
            if not addr_from_pk_processed:
                state_container.paginated_tx_hash.insert(
                    address_state, self.txhash)
        address_state.increase_nonce()
        state_container.paginated_bitfield.set_ots_key(
            state_container.addresses_state, addr_from_pk, self.ots_key)

        return True
コード例 #4
0
ファイル: TokenTransaction.py プロジェクト: zeta1999/QRL
    def revert(self, state: State, state_container: StateContainer) -> bool:
        addr_from_pk = bytes(QRLHelper.getAddress(self.PK))
        owner_processed = False
        addr_from_processed = False
        addr_from_pk_processed = False

        for initial_balance in self.initial_balances:
            if initial_balance.address == self.owner:
                owner_processed = True
            if initial_balance.address == self.addr_from:
                addr_from_processed = True
            if initial_balance.address == addr_from_pk:
                addr_from_pk_processed = True

            address_state = state_container.addresses_state[
                initial_balance.address]
            state_container.tokens.data[(initial_balance.address,
                                         self.txhash)] = TokenBalance(
                                             balance=0, delete=True)
            state_container.paginated_tx_hash.remove(address_state,
                                                     self.txhash)
            state_container.paginated_tokens_hash.remove(
                address_state, self.txhash)

        if not owner_processed:
            address_state = state_container.addresses_state[self.owner]
            state_container.paginated_tx_hash.remove(address_state,
                                                     self.txhash)

        address_state = state_container.addresses_state[self.addr_from]
        address_state.update_balance(state_container, self.fee)
        if not addr_from_processed and self.addr_from != self.owner:
            state_container.paginated_tx_hash.remove(address_state,
                                                     self.txhash)

        address_state = state_container.addresses_state[addr_from_pk]
        if self.addr_from != addr_from_pk and addr_from_pk != self.owner:
            if not addr_from_pk_processed:
                state_container.paginated_tx_hash.remove(
                    address_state, self.txhash)
        address_state.decrease_nonce()
        state_container.paginated_bitfield.unset_ots_key(
            state_container.addresses_state, addr_from_pk, self.ots_key)

        return True
コード例 #5
0
    def test_revert_transfer_token_txn(self):
        """
        Alice has 1000 tokens and 100 QRL, Bob has none. Alice sends some tokens to Bob.
        Let's undo this.
        """
        tx = TransferTokenTransaction.create(**self.params)
        tx.sign(self.alice)
        addresses_state = dict(self.addresses_state)
        addresses_state[self.alice.address].pbdata.balance = 100
        addresses_state[self.bob.address].pbdata.balance = 0
        tokens = Indexer(b'token', None)
        tokens.data[(self.alice.address,
                     tx.token_txhash)] = TokenBalance(balance=1000)
        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(
            tokens.data[(self.alice.address, tx.token_txhash)].balance, 1000)
        self.assertEqual(
            tokens.data[(self.bob.address, tx.token_txhash)].balance, 0)
コード例 #6
0
    def test_revert_transfer_token_txn_send_tokens_to_self(self):
        """
        Alice has 1000 tokens and 100 QRL. She sends some tokens to herself.
        Can we undo this?
        """
        self.params["addrs_to"] = [self.alice.address]
        tx = TransferTokenTransaction.create(**self.params)
        tx.sign(self.alice)
        addresses_state = dict(self.addresses_state)
        addresses_state[self.alice.address].pbdata.balance = 100
        tokens = Indexer(b'token', None)
        tokens.data[(self.alice.address,
                     tx.token_txhash)] = TokenBalance(balance=100)
        state_container = StateContainer(addresses_state=addresses_state,
                                         tokens=tokens,
                                         slaves=Indexer(b'slave', None),
                                         lattice_pk=Indexer(
                                             b'lattice_pk', None),
                                         multi_sig_spend_txs=dict(),
                                         votes_stats=dict(),
                                         block_number=1,
                                         total_coin_supply=1000,
                                         current_dev_config=config.dev,
                                         write_access=True,
                                         my_db=self.state._db,
                                         batch=None)
        state_container.paginated_bitfield.set_ots_key(addresses_state,
                                                       self.alice.address, 0)

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

        self.assertEqual(addresses_state[self.alice.address].balance, 100)
        # Unfortunately importing mock.call results in some sort of ValueError so I can't check the arguments.
        self.assertEqual(
            tokens.data[(self.alice.address, tx.token_txhash)].balance, 100)
コード例 #7
0
    def test_revert_transfer_token_txn_empty_addresses_state(self):
        """
        If we didn't have any AddressStates for the addresses involved in this test, do nothing
        """
        tx = TransferTokenTransaction.create(**self.params)
        tx.sign(self.alice)
        addresses_state = dict(self.addresses_state)
        tokens = Indexer(b'token', None)
        tokens.data[(self.alice.address,
                     tx.token_txhash)] = TokenBalance(balance=100)
        state_container = StateContainer(addresses_state=addresses_state,
                                         tokens=tokens,
                                         slaves=Indexer(b'slave', None),
                                         lattice_pk=Indexer(
                                             b'lattice_pk', None),
                                         multi_sig_spend_txs=dict(),
                                         votes_stats=dict(),
                                         block_number=1,
                                         total_coin_supply=1000,
                                         current_dev_config=config.dev,
                                         write_access=True,
                                         my_db=self.state._db,
                                         batch=None)
        state_container.paginated_bitfield.set_ots_key(addresses_state,
                                                       self.alice.address, 0)

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

        self.assertEqual(
            100, tokens.data[(self.alice.address, tx.token_txhash)].balance)
        self.assertEqual(
            0, tokens.data[(self.bob.address, tx.token_txhash)].balance)
コード例 #8
0
    def test_apply_transfer_token_txn_send_tokens_to_self(self):
        """
        Alice has 1000 tokens and 100 QRL. She sends some tokens to herself. What happens next?
        """
        self.params["addrs_to"] = [self.alice.address]
        tx = TransferTokenTransaction.create(**self.params)
        tx.sign(self.alice)
        addresses_state = dict(self.addresses_state)
        tokens = Indexer(b'token', None)
        tokens.data[(self.alice.address,
                     tx.token_txhash)] = TokenBalance(balance=100)
        state_container = StateContainer(addresses_state=addresses_state,
                                         tokens=tokens,
                                         slaves=Indexer(b'slave', None),
                                         lattice_pk=Indexer(
                                             b'lattice_pk', None),
                                         multi_sig_spend_txs=dict(),
                                         votes_stats=dict(),
                                         block_number=1,
                                         total_coin_supply=1000,
                                         current_dev_config=config.dev,
                                         write_access=True,
                                         my_db=self.state._db,
                                         batch=None)

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

        self.assertEqual(addresses_state[self.alice.address].balance, 99)
        self.assertEqual(
            tokens.data[(self.alice.address, tx.token_txhash)].balance, 100)