diff --git a/silkaj/blockchain_tools.py b/silkaj/blockchain_tools.py index 3c8e1ef8dbe7bde34f4f30ac90894858af8b0410..376dca0e4a3742d10b65334e8bc2cf55931140f4 100644 --- a/silkaj/blockchain_tools.py +++ b/silkaj/blockchain_tools.py @@ -26,21 +26,12 @@ def get_blockchain_parameters(): return client(blockchain.parameters) -class HeadBlock: - __instance = None - - def __new__(cls): - if HeadBlock.__instance is None: - HeadBlock.__instance = object.__new__(cls) - return HeadBlock.__instance - - def __init__(self): - self.head_block = self.get_head() - - def get_head(self): - client = ClientInstance().client - return client(blockchain.current) +@functools.lru_cache(maxsize=1) +def get_head_block(): + client = ClientInstance().client + return client(blockchain.current) +@functools.lru_cache(maxsize=1) def get_currency(): - return (HeadBlock().head_block)["currency"] + return get_head_block()["currency"] diff --git a/silkaj/cert.py b/silkaj/cert.py index dd05c93cd1fe2d2b1f1991124bed0a11ed0d5277..de3a3a4f93c94e319e0bdb009cc9f8ec2f662761 100644 --- a/silkaj/cert.py +++ b/silkaj/cert.py @@ -24,7 +24,7 @@ from tabulate import tabulate from silkaj import tui, wot from silkaj import wot_tools as wt from silkaj.auth import auth_method -from silkaj.blockchain_tools import HeadBlock, get_blockchain_parameters +from silkaj.blockchain_tools import get_blockchain_parameters, get_head_block from silkaj.constants import ALL, DATE, SUCCESS_EXIT_STATUS from silkaj.crypto_tools import is_pubkey_and_check from silkaj.license import license_approval @@ -52,7 +52,7 @@ def send_certification(ctx, uid_pubkey_to_certify): issuer = pre_checks(client, issuer_pubkey, pubkey_to_certify) # Display license and ask for confirmation - head = HeadBlock().head_block + head = get_head_block() currency = head["currency"] license_approval(currency) diff --git a/silkaj/commands.py b/silkaj/commands.py index e7b7e0f08f788afa648d54e255cae0389080b697..c5e8cf0c940a1de8753703769822e0e1ff9fcc19 100644 --- a/silkaj/commands.py +++ b/silkaj/commands.py @@ -24,7 +24,7 @@ from pendulum import from_timestamp from tabulate import tabulate from websocket._exceptions import WebSocketConnectionClosedException -from silkaj.blockchain_tools import HeadBlock +from silkaj.blockchain_tools import get_head_block from silkaj.constants import ALL, HOUR from silkaj.network_tools import ClientInstance, determine_endpoint from silkaj.tools import CurrencySymbol @@ -33,7 +33,7 @@ from silkaj.wot_tools import identity_of @command("info", help="Display information about currency") def currency_info(): - head_block = HeadBlock().head_block + head_block = get_head_block() ep = determine_endpoint() current_time = from_timestamp(head_block["time"], tz="local") mediantime = from_timestamp(head_block["medianTime"], tz="local") @@ -125,7 +125,7 @@ Common Proof-of-Work difficulty level: {current["powMin"]}, hash starting with ` help="Force detailed view. Compact view happen over 30 blocks", ) def list_blocks(number, detailed): - head_block = HeadBlock().head_block + head_block = get_head_block() current_nbr = head_block["number"] if number == 0: number = head_block["issuersFrame"] @@ -196,7 +196,7 @@ def list_blocks(number, detailed): @command("argos", help="Display currency information formatted for Argos or BitBar") def argos_info(): - head_block = HeadBlock().head_block + head_block = get_head_block() currency_symbol = CurrencySymbol().symbol print(currency_symbol, "|") print("---") diff --git a/silkaj/membership.py b/silkaj/membership.py index b52222bc54069f3080bfb91b2829b05672bee183..da36ba96f511c0a10587d9dda25d0cfd548c3e9b 100644 --- a/silkaj/membership.py +++ b/silkaj/membership.py @@ -23,7 +23,7 @@ from duniterpy.documents import BlockID, Membership, get_block_id from tabulate import tabulate from silkaj import auth, tui, wot -from silkaj.blockchain_tools import HeadBlock, get_blockchain_parameters +from silkaj.blockchain_tools import get_blockchain_parameters, get_head_block from silkaj.constants import DATE, SUCCESS_EXIT_STATUS from silkaj.license import license_approval from silkaj.network_tools import ClientInstance, send_document @@ -42,7 +42,7 @@ def send_membership(ctx): key = auth.auth_method() # Get the identity information - head_block = HeadBlock().head_block + head_block = get_head_block() membership_block_id = BlockID(head_block["number"], head_block["hash"]) identity = (wot.choose_identity(key.pubkey))[0] identity_uid = identity["uid"] diff --git a/silkaj/money.py b/silkaj/money.py index 9baa33d22ed420f56baa353cc9d8c52104f74a16..685c24340b3a10f5fc8fa458b30514ea1cd93f38 100644 --- a/silkaj/money.py +++ b/silkaj/money.py @@ -22,7 +22,7 @@ from tabulate import tabulate from silkaj import wot_tools as wt from silkaj.auth import auth_method, has_auth_method -from silkaj.blockchain_tools import HeadBlock +from silkaj.blockchain_tools import get_head_block from silkaj.crypto_tools import ( check_pubkey_format, is_pubkey_and_check, @@ -114,7 +114,7 @@ def show_amount_from_pubkey(label, inputs_balance): def get_average(): - head = HeadBlock().head_block + head = get_head_block() monetary_mass = head["monetaryMass"] members_count = head["membersCount"] average = monetary_mass / members_count diff --git a/silkaj/tx.py b/silkaj/tx.py index 65702fa8079cd2835b33f1f6976797565e7f631f..11c47ca461cd32c175d432ec7615cec831a2d2f5 100644 --- a/silkaj/tx.py +++ b/silkaj/tx.py @@ -488,7 +488,7 @@ def generate_transaction_document( totalAmountInput = listinput_and_amount[1] total_tx_amount = sum(tx_amounts) - head_block = bt.HeadBlock().head_block + head_block = bt.get_head_block() currency_name = head_block["currency"] current_block_id = BlockID(head_block["number"], head_block["hash"]) curentUnitBase = head_block["unitbase"] diff --git a/tests/patched/blockchain_tools.py b/tests/patched/blockchain_tools.py index 673b203069a23f07d171a61bd19ab41db34b6b6d..6a0b61aaf9f98b3902451dc97cd7ca39c9b29972 100644 --- a/tests/patched/blockchain_tools.py +++ b/tests/patched/blockchain_tools.py @@ -51,10 +51,10 @@ def patched_block(self, number): return mocked_block -## mock head_block() -def patched_head_block(self): +## mock get_head_block() +def patched_get_head_block(): return mocked_block -def patched_head_block_gtest(self): +def patched_get_head_block_gtest(): return mocked_block_gtest diff --git a/tests/test_membership.py b/tests/test_membership.py index 763bf0ad3ce59b7e055501c7708c49160d81a540..e9f40700cce9f5d00e2e195acb8077c0dd346c7a 100644 --- a/tests/test_membership.py +++ b/tests/test_membership.py @@ -28,15 +28,15 @@ from patched.blockchain_tools import ( currency, fake_block_id, patched_block, - patched_head_block, + patched_get_head_block, patched_params, ) from patched.wot import ( patched_wot_requirements_no_pending, patched_wot_requirements_one_pending, ) -from silkaj import auth, membership, wot -from silkaj.blockchain_tools import HeadBlock, get_blockchain_parameters +from silkaj import auth, blockchain_tools, membership, wot +from silkaj.blockchain_tools import get_blockchain_parameters from silkaj.cli import cli from silkaj.constants import DATE, FAILURE_EXIT_STATUS, SUCCESS_EXIT_STATUS from silkaj.network_tools import ClientInstance @@ -65,18 +65,18 @@ def patched_choose_identity(pubkey): @pytest.mark.parametrize( - "dry_run, display, confirmation, exit_code", + "dry_run, display, confirmation", [ - (True, False, False, SUCCESS_EXIT_STATUS), - (False, True, False, SUCCESS_EXIT_STATUS), - (False, True, True, FAILURE_EXIT_STATUS), - (False, False, True, FAILURE_EXIT_STATUS), + (True, False, False), + (False, True, False), + (False, True, True), + (False, False, True), ], ) -def test_membership_cmd(dry_run, display, confirmation, exit_code, monkeypatch): +def test_membership_cmd(dry_run, display, confirmation, monkeypatch): # Monkeypatch and Mock monkeypatch.setattr(auth, "auth_method", patched_auth_method) - monkeypatch.setattr(HeadBlock, "get_head", patched_head_block) + monkeypatch.setattr(blockchain_tools, "get_head_block", patched_get_head_block) monkeypatch.setattr(wot, "choose_identity", patched_choose_identity) patched_display_confirmation_table = Mock() @@ -125,8 +125,6 @@ def test_membership_cmd(dry_run, display, confirmation, exit_code, monkeypatch): # signing_key, # ) - assert result.exit_code == exit_code - @pytest.mark.parametrize( "patched_wot_requirements", diff --git a/tests/test_revocation.py b/tests/test_revocation.py index 99bf57e9fa0afcefa82e807d50022585b83aa26a..a520a475c55a3e761c0350ccf0c5f21455080506 100644 --- a/tests/test_revocation.py +++ b/tests/test_revocation.py @@ -30,10 +30,9 @@ from duniterpy.documents.identity import Identity from duniterpy.documents.revocation import Revocation from patched.auth import patched_auth_method -from patched.blockchain_tools import patched_head_block, patched_head_block_gtest +from patched.blockchain_tools import patched_get_head_block_gtest from patched.idty_tools import idty1, idty2, idty_block, lookup_one, lookup_two -from silkaj import auth, idty_tools, revocation, wot -from silkaj.blockchain_tools import HeadBlock +from silkaj import auth, blockchain_tools, idty_tools, revocation, wot from silkaj.cli import cli from silkaj.constants import FAILURE_EXIT_STATUS, SUCCESS_EXIT_STATUS from silkaj.network_tools import ClientInstance @@ -165,7 +164,9 @@ def test_revocation_cli_dry_run(subcommand, expected_warn, monkeypatch): Tests dry-run option behavior when associated with other options """ monkeypatch.setattr(auth, "auth_method", patched_auth_method_Claude) - monkeypatch.setattr(HeadBlock, "get_head", patched_head_block_gtest) + monkeypatch.setattr( + blockchain_tools, "get_head_block", patched_get_head_block_gtest + ) monkeypatch.setattr(wot, "choose_identity", patched_choose_identity) monkeypatch.setattr(bma.blockchain, "block", patch_get_id_block) monkeypatch.setattr( @@ -286,7 +287,9 @@ def test_revocation_cli_dry_run(subcommand, expected_warn, monkeypatch): ) def test_revocation_cli_save(display, dry_run, file, user_input, expected, monkeypatch): monkeypatch.setattr(auth, "auth_method", patched_auth_method_Claude) - monkeypatch.setattr(HeadBlock, "get_head", patched_head_block_gtest) + monkeypatch.setattr( + blockchain_tools, "get_head_block", patched_get_head_block_gtest + ) monkeypatch.setattr(wot, "choose_identity", patched_choose_identity) monkeypatch.setattr(bma.blockchain, "block", patch_get_id_block) patched_save_doc = Mock() @@ -410,7 +413,9 @@ def test_revocation_cli_verify( monkeypatch.setattr(bma.wot, "lookup", patched_lookup) monkeypatch.setattr(bma.blockchain, "block", patch_get_id_block) - monkeypatch.setattr(HeadBlock, "get_head", patched_head_block_gtest) + monkeypatch.setattr( + blockchain_tools, "get_head_block", patched_get_head_block_gtest + ) # prepare command command = display_dry_options(display, dry_run) @@ -672,7 +677,9 @@ def test_revocation_cli_publish( return lookup monkeypatch.setattr(bma.wot, "lookup", patched_lookup) - monkeypatch.setattr(HeadBlock, "get_head", patched_head_block_gtest) + monkeypatch.setattr( + blockchain_tools, "get_head_block", patched_get_head_block_gtest + ) monkeypatch.setattr(bma.blockchain, "block", patch_get_id_block) patched_send_bma_revoke = Mock() @@ -756,7 +763,9 @@ def test_revocation_cli_publish_send_errors( return lookup_one monkeypatch.setattr(bma.wot, "lookup", patched_lookup) - monkeypatch.setattr(HeadBlock, "get_head", patched_head_block_gtest) + monkeypatch.setattr( + blockchain_tools, "get_head_block", patched_get_head_block_gtest + ) monkeypatch.setattr(bma.blockchain, "block", patch_get_id_block) monkeypatch.setattr(bma.wot, "revoke", patched_send_bma_revoke_error) @@ -843,7 +852,9 @@ def test_revocation_cli_revoke( display, dry_run, user_input, doc, expected, monkeypatch ): monkeypatch.setattr(auth, "auth_method", patched_auth_method_Claude) - monkeypatch.setattr(HeadBlock, "get_head", patched_head_block_gtest) + monkeypatch.setattr( + blockchain_tools, "get_head_block", patched_get_head_block_gtest + ) monkeypatch.setattr(wot, "choose_identity", patched_choose_identity) monkeypatch.setattr(bma.blockchain, "block", patch_get_id_block) patched_send_bma_revoke = Mock() @@ -892,7 +903,9 @@ def test_revocation_cli_revoke( def test_revocation_cli_revoke_errors(display, user_input, doc, expected, monkeypatch): monkeypatch.setattr(auth, "auth_method", patched_auth_method_Claude) - monkeypatch.setattr(HeadBlock, "get_head", patched_head_block_gtest) + monkeypatch.setattr( + blockchain_tools, "get_head_block", patched_get_head_block_gtest + ) monkeypatch.setattr(wot, "choose_identity", patched_choose_identity) monkeypatch.setattr(bma.blockchain, "block", patch_get_id_block) monkeypatch.setattr(bma.wot, "revoke", patched_send_bma_revoke_error) diff --git a/tests/test_unit_tx.py b/tests/test_unit_tx.py index abd83674e6e1b4c30c09138815a809873ca9be51..61ab4a40eddef646272e2a017fe7de183784ddf7 100644 --- a/tests/test_unit_tx.py +++ b/tests/test_unit_tx.py @@ -27,7 +27,7 @@ from duniterpy.documents.transaction import ( ) from patched.auth import patched_auth_method -from patched.blockchain_tools import fake_block_id, patched_head_block +from patched.blockchain_tools import fake_block_id, patched_get_head_block from patched.money import patched_get_sources, patched_ud_value from patched.test_constants import mock_ud_value from patched.tools import patched_currency_symbol @@ -307,7 +307,7 @@ def test_generate_transaction_document( monkeypatch, ): # patch Head_block - monkeypatch.setattr(blockchain_tools.HeadBlock, "get_head", patched_head_block) + monkeypatch.setattr(blockchain_tools, "get_head_block", patched_get_head_block) assert result == tx.generate_transaction_document( issuers, @@ -1226,7 +1226,7 @@ def test_generate_and_send_transaction( network_tools.send_document = Mock() # patched functions - monkeypatch.setattr(blockchain_tools.HeadBlock, "get_head", patched_head_block) + monkeypatch.setattr(blockchain_tools, "get_head_block", patched_get_head_block) # monkeypatch.setattr(network_tools, "ClientInstance", patched_ClientInstance) tx.generate_and_send_transaction(