iota/transaction/creation.py
def finalize(self):
        # type: () -> None
        """
        Finalizes the bundle, preparing it to be attached to the Tangle.
        """
        if self.hash:
            raise RuntimeError('Bundle is already finalized.')

        if not self:
            raise ValueError('Bundle has no transactions.')

        # Quick validation.
        balance = self.balance

        if balance < 0:
            if self.change_address:
                self.add_transaction(ProposedTransaction(
                    address=self.change_address,
                    value=-balance,
                    tag=self.tag,
                ))
            else:
                raise ValueError(
                    'Bundle has unspent inputs (balance: {balance}); '
                    'use ``send_unspent_inputs_to`` to create '
                    'change transaction.'.format(
                        balance=balance,
                    ),
                )
        elif balance > 0:
            raise ValueError(
                'Inputs are insufficient to cover bundle spend '
                '(balance: {balance}).'.format(
                    balance=balance,
                ),
            )

        # Generate bundle hash.
        while True:
            sponge = Kerl()
            last_index = len(self) - 1

            for i, txn in enumerate(self):
                txn.current_index = i
                txn.last_index = last_index

                sponge.absorb(txn.get_signature_validation_trytes().as_trits())

            bundle_hash_trits = [0] * HASH_LENGTH
            sponge.squeeze(bundle_hash_trits)

            bundle_hash = BundleHash.from_trits(bundle_hash_trits)

            # Check that we generated a secure bundle hash.
            # https://github.com/iotaledger/iota.lib.py/issues/84
            if any(13 in part for part in normalize(bundle_hash)):
                # Increment the legacy tag and try again.
                tail_transaction = (
                    self.tail_transaction
                )  # type: ProposedTransaction
                tail_transaction.increment_legacy_tag()
            else:
                break

        # Copy bundle hash to individual transactions.
        for txn in self:
            txn.bundle_hash = bundle_hash

            # Initialize signature/message fragment.
            txn.signature_message_fragment = Fragment(txn.message or b'')
def finalize(self):
        # type: () -> None
        """
        Finalizes the bundle, preparing it to be attached to the Tangle.
        """
        if self.hash:
            raise RuntimeError('Bundle is already finalized.')

        if not self:
            raise ValueError('Bundle has no transactions.')

        # Quick validation.
        balance = self.balance

        if balance < 0:
            if self.change_address:
                self.add_transaction(ProposedTransaction(
                    address=self.change_address,
                    value=-balance,
                    tag=self.tag,
                ))
            else:
                raise ValueError(
                    'Bundle has unspent inputs (balance: {balance}); '
                    'use ``send_unspent_inputs_to`` to create '
                    'change transaction.'.format(
                        balance=balance,
                    ),
                )
        elif balance > 0:
            raise ValueError(
                'Inputs are insufficient to cover bundle spend '
                '(balance: {balance}).'.format(
                    balance=balance,
                ),
            )

        # Generate bundle hash.
        while True:
            sponge = Kerl()
            last_index = len(self) - 1

            for i, txn in enumerate(self):
                txn.current_index = i
                txn.last_index = last_index

                sponge.absorb(txn.get_signature_validation_trytes().as_trits())

            bundle_hash_trits = [0] * HASH_LENGTH
            sponge.squeeze(bundle_hash_trits)

            bundle_hash = BundleHash.from_trits(bundle_hash_trits)

            # Check that we generated a secure bundle hash.
            # https://github.com/iotaledger/iota.lib.py/issues/84
            if any(13 in part for part in normalize(bundle_hash)):
                # Increment the legacy tag and try again.
                tail_transaction = (
                    self.tail_transaction
                )  # type: ProposedTransaction
                tail_transaction.increment_legacy_tag()
            else:
                break

        # Copy bundle hash to individual transactions.
        for txn in self:
            txn.bundle_hash = bundle_hash

            # Initialize signature/message fragment.
            txn.signature_message_fragment = Fragment(txn.message or b'')
Finalizes the bundle, preparing it to be attached to the Tangle.