Skip to content

Bugfixing - Debugging 2025 #16

@luka-0614

Description

@luka-0614

Since no one has been interested in updating this port for a long time and the original repository on the python2 is poorly developed I decided to use the "pytest" tool to fix bugs here and update outdated features like for example: OpenSSL.
Everything was adapted to python 3.13

Update code - Py3Bitmesage 2025-12-07

src/bitmsghash/bitmsghash.cpp - fix error with OpenSSL in python3.11+

(18.0) - Replace this:

#include "openssl/sha.h" 

on this:

#include <openssl/evp.h> 

(45.0) - Replace this:

SHA512_CTX sha;

on this:

EVP_MD_CTX *ctx = NULL;
const EVP_MD *sha512 = EVP_sha512();

(60.0) - Replace this:

SHA512_Init(&sha);
SHA512_Update(&sha, buf, HASH_SIZE + sizeof(uint64_t));
SHA512_Final(output, &sha);
SHA512_Init(&sha);
SHA512_Update(&sha, output, HASH_SIZE);
SHA512_Final(output, &sha);

on this:

ctx = EVP_MD_CTX_new();
EVP_DigestInit_ex(ctx, sha512, NULL);
EVP_DigestUpdate(ctx, buf, HASH_SIZE + sizeof(uint64_t));
EVP_DigestFinal_ex(ctx, output, NULL);
EVP_MD_CTX_reset(ctx); 
EVP_DigestInit_ex(ctx, sha512, NULL); 
EVP_DigestUpdate(ctx, output, HASH_SIZE);
EVP_DigestFinal_ex(ctx, output, NULL);
EVP_MD_CTX_free(ctx);

And in bitmsghash folder
$ make clean && make

src/depends.py - old entries

(220.0) - remove this line:

logger.info('sqlite3 Module Version: %s', sqlite3.version)

plugins/plugin.py - Replace the entire script for newer requirements. Removal of obsolete pkg

# -*- coding: utf-8 -*-
"""
Operating with plugins
"""
import sys
import importlib
from types import ModuleType
from typing import Iterable, Callable, Any

try:
    import importlib.metadata as importlib_metadata
except ImportError:
    import importlib_metadata

def get_plugins(group: str, name: str = None) -> Iterable[tuple[str, Callable]]:
    entry_point_group = f'bitmessage.{group}'

    if sys.version_info >= (3, 10):
        eps = importlib_metadata.entry_points(group=entry_point_group)
    else:
        eps = importlib_metadata.entry_points().get(entry_point_group, [])

    for ep in eps:
        if name is None or ep.name == name:
            try:
                plugin = ep.load()
                yield ep.name, plugin
            except Exception as e:
                print(f"Problem while loading {ep.name}: {e}")

def get_plugin_version() -> str:
    try:
        return importlib_metadata.version("pybitmessage")
    except importlib_metadata.PackageNotFoundError:
        return "unknown"


__version__ = get_plugin_version()

src/bitmessageqt/settings.py - Residues of pkg_resources

(66.0) - Replace this:

try:
            import pkg_resources
        except ImportError:
            pass
        else:
            # Append proxy types defined in plugins
            # FIXME: this should be a function in mod:`plugin`
            for ep in pkg_resources.iter_entry_points(
                    'bitmessage.proxyconfig'):
                try:
                    ep.load()
                except Exception: # it should add only functional plugins
                    # many possible exceptions, which are don't matter
                    pass
                else:
                    self.comboBoxProxyType.addItem(ep.name)

On this:

try:
            import importlib.metadata as importlib_metadata
        except ImportError:
            import importlib_metadata

        if sys.version_info >= (3, 10):
            eps = importlib_metadata.entry_points(group='bitmessage.proxyconfig')
        else:
            eps = importlib_metadata.entry_points().get('bitmessage.proxyconfig', [])

        for ep in eps:
            try:
                ep.load()
            except Exception:
                pass
            else:
                self.comboBoxProxyType.addItem(ep.name)

src/bitmessageqt/init.py - Fixing the sound-related function error and solving the "pybitmessageqt.conf" file that additionally caused delay.

(1375) - Replace the entire "PlaySound" function:

    def playSound(self, category, label=None):
        if not config.safeGetBoolean('bitmessagesettings', 'playsounds'):
            return

        if not sound.is_connection_sound(category):
            if (datetime.now() - self.lastSoundTime).total_seconds() < self.maxSoundFrequencySec:
                return

        try:
            from PyQt5.QtMultimedia import QSound
        except ImportError:
            return

        if label:
            user_sound = os.path.join(state.appdata, 'sounds', label)
            for ext in ('.wav', '.ogg', '.mp3'):
                if os.path.isfile(user_sound + ext):
                    QSound.play(user_sound + ext)
                    if not sound.is_connection_sound(category):
                        self.lastSoundTime = datetime.now()
                    return

        base_path = os.path.join(paths.lookupResourceFolder(), 'sounds')
        sound_files = {
            sound.SOUND_CONNECTED: 'connected',
            sound.SOUND_CONNECTION_GREEN: 'green',
            sound.SOUND_DISCONNECTED: 'disconnected',
            sound.SOUND_MESSAGE: 'newmessage',
            sound.SOUND_KNOWN: 'known',
            sound.SOUND_UNKNOWN: 'unknown',
            sound.SOUND_SCREENSHOT: 'screenshot',
        }

        filename = sound_files.get(category)
        if not filename:
            return

        for ext in ('.wav', '.ogg', '.mp3'):
            full_path = os.path.join(base_path, filename + ext)
            if os.path.isfile(full_path):
                QSound.play(full_path)
                if not sound.is_connection_sound(category):
                    self.lastSoundTime = datetime.now()
                return

(4329.0) - Replace this:

QtCore.QCoreApplication.setOrganizationName("PyBitmessage")
QtCore.QCoreApplication.setOrganizationDomain("bitmessage.org")
QtCore.QCoreApplication.setApplicationName("pybitmessageqt")

on this:

        QtCore.QSettings.setPath(
            QtCore.QSettings.IniFormat,
            QtCore.QSettings.UserScope,
            "/dev/null" if not is_windows else "NUL"
        )

These changes will result in no errors with:
$ pytest pybitmessage/bitmessagemain.py
$ python3 pybitmessage/bitmessagemain.py

It also proposes to delete the old file "start.sh" which contains commands to run bitmessage in the old python 2 and the file "py3start.py" to change to "start_linux.sh".
Qt5 of python3 looks great compared to Qt4 (python2). In addition, python3 works much faster and has greater security when performing cryptographic functions and the entire code.
Additional proposal is to change the default settings in "keys.dat" that is, by default, disabled support to namecoin which currently does not work. It's not about the removal, it's about shutting down the entire code.

After my tests I conclude full compatibility with peers on python 2. But I will continue to try to fix things if they occur and introduce newer mechanics and optimize the code. Long live Bitmessage!.

I also think that if my changes are introduced in the official PyBitmessage-py3 repository and the community considers the code to be stable, it can be considered to be an entry into the new version of the program which proposes "0.7" compared to the latest snapshot of the official version "0.63.2". If the main developer of the original "Peter Surda" repository were interested in implementing the update, the whole could be moved to the new repository by ceasing improvements over pybitmessage python2 and classifying it as obsolete.

That's all for now. I'm going to sit by the code, and I'm going to be here publishing more updates. If anyone finds anything, I invite you to discuss it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions