Skip to content
Snippets Groups Projects
Select Git revision
  • 86f8b2f665b88ae36353a6ead0945a4928a8b3b2
  • main default protected
  • release/1.1
  • encrypt_comments
  • mnemonic_dewif
  • authors_rules
  • 0.14
  • rtd
  • 1.2.1 protected
  • 1.2.0 protected
  • 1.1.1 protected
  • 1.1.0 protected
  • 1.0.0 protected
  • 1.0.0rc1 protected
  • 1.0.0rc0 protected
  • 1.0.0-rc protected
  • 0.62.0 protected
  • 0.61.0 protected
  • 0.60.1 protected
  • 0.58.1 protected
  • 0.60.0 protected
  • 0.58.0 protected
  • 0.57.0 protected
  • 0.56.0 protected
  • 0.55.1 protected
  • 0.55.0 protected
  • 0.54.3 protected
  • 0.54.2 protected
28 results

duniterpy.api.bma.html

Blame
  • functions.py 8.35 KiB
    import os
    
    from adapters.duniter_v18.blocks import LevelDBBlocksRepository
    from adapters.duniter_v18.certifications import LevelDBCertificationsRepository
    from adapters.duniter_v18.identities import LevelDBIdentitiesRepository
    from adapters.duniter_v18.memberships import LevelDBMembershipsRepository
    from adapters.duniter_v18.wallets import LevelDBWalletsRepository
    from lib.utility import *
    
    DEFAULT_LEVELDB_PATH = "./leveldb"
    
    
    def load_json_url(path):
        with open(path, "r") as fd:
            return json.load(fd)
    
    
    def get_wallets_data():
        # Get wallets balances data
        wallets_repository = LevelDBWalletsRepository(os.getenv("LEVELDB_PATH", DEFAULT_LEVELDB_PATH))
        wallets = {}
        total_money = 0  # counter
        ignored_money = 0  # counter
        for unlock_expression, wallet in wallets_repository:
            balance = wallet["balance"]
            if "&&" in unlock_expression:
                ignored_money += balance
                continue
            pubkey = unlock_expression.split("(")[1].split(")")[0]
    
            # Remove pubkeys > 32 bytes
            # d2meevcahfts2gqmvmrw5hzi25jddikk4nc4u1fkwrau
            # afv1d5xa7fcdhcta1bqfq3pwvwem16gw67qj37obgnsv
            # dyvfr3fqbs6g1yrktbstzxdkj3n7c5hrqf9buddzne4o
            # 11111111111111111111111111111111111111111111
            # jUPLL2BgY2QpheWEY3R13edV2Y4tvQMCXjJVM8PGDvyd
            # gatrpfmgsuez193bja5snivz3dsvsqn5kcm4ydtpknsy
            pubkey_bytes = base58.b58decode(pubkey)
            pubkey_length = len(pubkey_bytes)
            if pubkey_length > 32 or balance == 0:
                ignored_money += balance
                continue
    
            wallets.update({v1_pubkey_to_v2_address(pubkey): int(balance)})
            total_money += balance
    
        return wallets, total_money, ignored_money
    
    
    def get_identities_and_wallets(start_timestamp):
        """get identities with certifications and wallets with their balance
        start_timestamp is the timestamp of the v2 genesis
            used to estimate cert expiration in number of blocks
        """
        # initialize
        blocs = {}
        identity_names = {}
        identities = {}
        treasury = 0
    
        # Get last block info
        last_block = load_json_url("inputs/ud_value.json")[0]["value"]
        initial_monetary_mass = last_block["mass"]
        last_block_time = last_block["medianTime"]
    
        print("    parse Identities...")
        # Get leveldb indices as Dex data
        memberships_repository = LevelDBMembershipsRepository(os.getenv("LEVELDB_PATH", DEFAULT_LEVELDB_PATH))
        identities_repository = LevelDBIdentitiesRepository(os.getenv("LEVELDB_PATH", DEFAULT_LEVELDB_PATH))
        certifications_repository = LevelDBCertificationsRepository(os.getenv("LEVELDB_PATH", DEFAULT_LEVELDB_PATH))
        blocks_repository = LevelDBBlocksRepository(os.getenv("LEVELDB_PATH", DEFAULT_LEVELDB_PATH))
    
        # Get identities switches
        addresses_switches = load_json("custom/addresses_switches.json")
        # Get custom identities
        custom_identities = load_json("custom/identities.json")
    
        # Get wallets data
        print("    parse Wallets...")
        (wallets, total_money, ignored_money) = get_wallets_data()
        # add ignored money to treasury and check initial monetary mass
        treasury += ignored_money  # add ignored money to treasury
        wallet_sum = total_money + ignored_money
        missing_money = initial_monetary_mass - wallet_sum
        if missing_money != 0:
            print(f"⚠️ initial monetary mass {initial_monetary_mass:,} does not equal wallet sum {wallet_sum:,}")
            print(f"money on the wallets: {total_money:,}")
            print(f"money from ignored sources: {ignored_money:,}")
            print(f"missing money (added to treasury): {missing_money:,}")
            # add missing money to treasury
            treasury += missing_money
        # FIXME get real treasury address
        wallets["5EYCAe5ijiYfyeZ2JJCGq56LmPyNRAKzpG4QkoQkkQNB5e6Z"] = treasury
    
        # TODO make sure that index respects order of arrival
        # Get identities names by pubkey
        for pubkey, identity in identities_repository:
            address = v1_pubkey_to_v2_address(pubkey)
            index = identity["wotb_id"] + 1
            uid = identity["uid"]
            is_member = identity["member"]
            identity_names[pubkey] = uid
            membership_expire_on = date_to_bloc_number(memberships_repository.get(pubkey)["expires_on"], start_timestamp)
            if membership_expire_on < 0:
                membership_expire_on = 0  # forget old expiry date
    
            # add address and balance to identity
            if address not in wallets:
                balance = 0
            else:
                balance = wallets[address]
                # remove identity from wallet
                # (only let simple wallets)
                del wallets[address]
    
            # fill in identity entry
            identities[uid] = {
                "index": index,
                "owner_key": address,
                "balance": balance,
                "membership_expire_on": membership_expire_on if is_member else 0,
                "next_cert_issuable_on": 0,  # initialized to zero, modified later
                "certs_received": {},
            }
    
            # Switch address to custom if exist
            if uid in addresses_switches.keys():
                identities[uid]["owner_key"] = addresses_switches[uid]["v2"]
                identities[uid]["old_owner_key"] = v1_pubkey_to_v2_address(
                    addresses_switches[uid]["v1"]
                )
    
        # Add custom identities
        identities.update(custom_identities)
    
        # get info from block
        for block_number, block in blocks_repository:
            blocs[block_number] = block["medianTime"]
    
        # Generate identities Ğ1v2 genesis json bloc
        # certs are stored per issuer in input file
        # certs are stored per receiver in output file
        print("    parse certifications...")
        # get certifications updated to their last state
        for i_pubkey, issuer in certifications_repository:
            i_uid = identity_names[i_pubkey]
            i_address = v1_pubkey_to_v2_address(i_pubkey)
    
            # get certifications updated to their last state
            for cert in issuer["issued"]:
                # if certification expired, skip silently
                if cert["expired_on"] != 0:
                    continue
    
                r_pubkey = cert["receiver"]
                r_uid = identity_names[r_pubkey]
                r_address = v1_pubkey_to_v2_address(r_pubkey)
    
                # get expiration of certification
                # timestamp of cert creation
                created_at = blocs[cert["created_on"]]
                # block of cert creation
                created_on = date_to_bloc_number(created_at, start_timestamp)
                # block of next issuable cert
                next_issuable_on = created_on + CERT_PERIOD
                # timestamp of cert expiration
                cert_expire_at = cert["expires_on"]
                cert_expire_on = date_to_bloc_number(cert_expire_at, start_timestamp)
    
                # if certification expiration date is before export,
                # it is a renewed certification and can be ignored
                if cert_expire_at < last_block_time:
                    continue
                # certifications can also have expired between export and start_timestamp
                # in this case we display a warning because these missing certification
                # could lead to a genesis with not enough certifications received for some members
                if cert_expire_at <= start_timestamp:
                    print(f"⚠️ {i_uid}{r_uid} cert expired between export and start")
                    continue
                # bump the next issuable date if necessary
                elif next_issuable_on > identities[i_uid]["next_cert_issuable_on"]:
                    identities[i_uid]["next_cert_issuable_on"] = next_issuable_on
    
                # add received certification to identity
                identities[r_uid]["certs_received"][i_uid] = cert_expire_on
    
        return identities, wallets
    
    
    def get_smiths():
        final_smiths = {}
        smiths_brut = load_json("custom/smiths.json")
        for smith in smiths_brut:
            final_smiths.update(smith)
    
        return final_smiths
    
    
    def get_technical_committee():
        return load_json("custom/technical_committee.json")
    
    
    def fix_identities_with_not_enough_certs(identities):
        """some identities do not have enough certs received
        this function set their membership_expire_on to 0"""
        for key, value in identities.items():
            received_count = len(value["certs_received"])
            if value["membership_expire_on"] > 0 and received_count < CERT_MIN_RECEIVED_CERT_TO_ISSUE_CERT:
                print(f"⚠️ {key} has received only {received_count} certs, disabling it")
                value["membership_expire_on"] = 0