Exemplo n.º 1
0
    def _remove_from_index(self, tx: BaseTransaction, index: int) -> None:
        """ Remove tx from mint/melt indexes and total amount
        """
        assert tx.hash is not None

        tx_output = tx.outputs[index]
        token_uid = tx.get_token_uid(tx_output.get_token_index())

        if tx_output.is_token_authority():
            if tx_output.can_mint_token():
                # remove from mint index
                self.tokens[token_uid].mint.discard((tx.hash, index))
            if tx_output.can_melt_token():
                # remove from melt index
                self.tokens[token_uid].melt.discard((tx.hash, index))
        else:
            self.tokens[token_uid].total -= tx_output.value
Exemplo n.º 2
0
    def _add_to_index(self, tx: BaseTransaction, index: int) -> None:
        """ Add tx to mint/melt indexes and total amount
        """
        assert tx.hash is not None

        tx_output = tx.outputs[index]
        token_uid = tx.get_token_uid(tx_output.get_token_index())

        if tx_output.is_token_authority():
            if tx_output.can_mint_token():
                # add to mint index
                self.tokens[token_uid].mint.add((tx.hash, index))
            if tx_output.can_melt_token():
                # add to melt index
                self.tokens[token_uid].melt.add((tx.hash, index))
        else:
            self.tokens[token_uid].total += tx_output.value
    def _remove_utxo(self, tx: BaseTransaction, index: int) -> None:
        """ Remove tx from mint/melt indexes and total amount
        """
        assert tx.hash is not None

        tx_output = tx.outputs[index]
        token_uid = tx.get_token_uid(tx_output.get_token_index())

        if tx_output.is_token_authority():
            if tx_output.can_mint_token():
                # remove from mint index
                self._remove_authority_utxo(token_uid,
                                            tx.hash,
                                            index,
                                            is_mint=True)
            if tx_output.can_melt_token():
                # remove from melt index
                self._remove_authority_utxo(token_uid,
                                            tx.hash,
                                            index,
                                            is_mint=False)
        else:
            self._subtract_from_total(token_uid, tx_output.value)
    def _add_utxo(self, tx: BaseTransaction, index: int) -> None:
        """ Add tx to mint/melt indexes and total amount
        """
        assert tx.hash is not None

        tx_output = tx.outputs[index]
        token_uid = tx.get_token_uid(tx_output.get_token_index())

        if tx_output.is_token_authority():
            if tx_output.can_mint_token():
                # add to mint index
                self._add_authority_utxo(token_uid,
                                         tx.hash,
                                         index,
                                         is_mint=True)
            if tx_output.can_melt_token():
                # add to melt index
                self._add_authority_utxo(token_uid,
                                         tx.hash,
                                         index,
                                         is_mint=False)
        else:
            self._add_to_total(token_uid, tx_output.value)
Exemplo n.º 5
0
    def on_new_tx(self, tx: BaseTransaction) -> None:
        """Checks the inputs and outputs of a transaction for matching keys.

        If an output matches, will add it to the unspent_txs dict.
        If an input matches, removes from unspent_txs dict and adds to spent_txs dict.
        """
        assert tx.hash is not None

        updated = False

        # check outputs
        for index, output in enumerate(tx.outputs):
            script_type_out = parse_address_script(output.script)
            if script_type_out:
                if script_type_out.address in self.keys:
                    token_id = tx.get_token_uid(output.get_token_index())
                    # this wallet received tokens
                    utxo = UnspentTx(tx.hash,
                                     index,
                                     output.value,
                                     tx.timestamp,
                                     script_type_out.address,
                                     output.token_data,
                                     timelock=script_type_out.timelock)
                    self.unspent_txs[token_id][(tx.hash, index)] = utxo
                    # mark key as used
                    self.tokens_received(script_type_out.address)
                    updated = True
                    # publish new output and new balance
                    self.publish_update(HathorEvents.WALLET_OUTPUT_RECEIVED,
                                        total=self.get_total_tx(),
                                        output=utxo)
            else:
                # it's the only one we know, so log warning
                self.log.warn('unknown script')

        # check inputs
        for _input in tx.inputs:
            assert tx.storage is not None
            output_tx = tx.storage.get_transaction(_input.tx_id)
            output = output_tx.outputs[_input.index]
            token_id = output_tx.get_token_uid(output.get_token_index())

            script_type_out = parse_address_script(output.script)
            if script_type_out:
                if script_type_out.address in self.keys:
                    # this wallet spent tokens
                    # remove from unspent_txs
                    key = (_input.tx_id, _input.index)
                    old_utxo = self.unspent_txs[token_id].pop(key, None)
                    if old_utxo is None:
                        old_utxo = self.maybe_spent_txs[token_id].pop(
                            key, None)
                    if old_utxo:
                        # add to spent_txs
                        spent = SpentTx(tx.hash, _input.tx_id, _input.index,
                                        old_utxo.value, tx.timestamp)
                        self.spent_txs[key].append(spent)
                        updated = True
                        # publish spent output and new balance
                        self.publish_update(HathorEvents.WALLET_INPUT_SPENT,
                                            output_spent=spent)
                    else:
                        # If we dont have it in the unspent_txs, it must be in the spent_txs
                        # So we append this spent with the others
                        if key in self.spent_txs:
                            output_tx = tx.storage.get_transaction(
                                _input.tx_id)
                            output = output_tx.outputs[_input.index]
                            spent = SpentTx(tx.hash, _input.tx_id,
                                            _input.index, output.value,
                                            tx.timestamp)
                            self.spent_txs[key].append(spent)
            else:
                self.log.warn('unknown input data')

        if updated:
            # TODO update history file?
            # XXX should wallet always update it or it will be called externally?
            self.update_balance()