From ad2d510b202f1b6154dc0d593482fea10db55ad3 Mon Sep 17 00:00:00 2001 From: Alex Li Date: Sun, 12 May 2024 14:50:30 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A5=20Tear=20down=20`AtomicalsCoin`=20?= =?UTF-8?q?to=20`AtomicalsCoinMixin`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- electrumx/lib/coins.py | 23 +++-------------------- electrumx/server/block_processor.py | 6 +++--- electrumx/server/daemon.py | 8 +++++--- electrumx/server/env.py | 10 +++++----- electrumx/server/mempool.py | 6 +++--- tests/test_blocks.py | 4 ++-- tests/test_transactions.py | 6 +++--- 7 files changed, 24 insertions(+), 39 deletions(-) diff --git a/electrumx/lib/coins.py b/electrumx/lib/coins.py index 0c7827dd..95d9b1e0 100644 --- a/electrumx/lib/coins.py +++ b/electrumx/lib/coins.py @@ -283,30 +283,13 @@ def bucket_estimatefee_block_target(cls, n: int) -> int: return n -class AtomicalsCoin(Coin): +class AtomicalsCoinMixin: ATOMICALS_ACTIVATION_HEIGHT: int ATOMICALS_ACTIVATION_HEIGHT_DMINT: int ATOMICALS_ACTIVATION_HEIGHT_COMMITZ: int ATOMICALS_ACTIVATION_HEIGHT_DENSITY: int ATOMICALS_ACTIVATION_HEIGHT_DFT_BITWORK_ROLLOVER: int - @classmethod - def lookup_coin_class(cls, name, net): - """Return a coin class given name and network. - Raise an exception if unrecognised.""" - req_attrs = ('TX_COUNT', 'TX_COUNT_HEIGHT', 'TX_PER_BLOCK') - for coin in util.subclasses(AtomicalsCoin): - if coin.NAME.lower() == name.lower() and coin.NET.lower() == net.lower(): - missing = [ - attr - for attr in req_attrs - if not hasattr(coin, attr) - ] - if missing: - raise CoinError(f'coin {name} missing {missing} attributes') - return coin - raise CoinError(f'unknown coin {name} and network {net} combination') - class AuxPowMixin: STATIC_BLOCK_HEADERS = False @@ -654,7 +637,7 @@ def warn_old_client_on_tx_broadcast(cls, client_ver): return False -class Bitcoin(BitcoinMixin, AtomicalsCoin): +class Bitcoin(BitcoinMixin, AtomicalsCoinMixin, Coin): NAME = "Bitcoin" DESERIALIZER = lib_tx.DeserializerSegWit MEMPOOL_HISTOGRAM_REFRESH_SECS = 120 @@ -938,7 +921,7 @@ class BitcoinSVRegtest(BitcoinSVTestnet): GENESIS_ACTIVATION = 10_000 -class BitcoinTestnet(BitcoinTestnetMixin, AtomicalsCoin): +class BitcoinTestnet(BitcoinTestnetMixin, AtomicalsCoinMixin, Coin): '''Bitcoin Testnet for Core bitcoind >= 0.13.1.''' NAME = "Bitcoin" DESERIALIZER = lib_tx.DeserializerSegWit diff --git a/electrumx/server/block_processor.py b/electrumx/server/block_processor.py index abe025cf..3f1d221c 100644 --- a/electrumx/server/block_processor.py +++ b/electrumx/server/block_processor.py @@ -11,7 +11,7 @@ import asyncio import os import time -from typing import Sequence, Tuple, List, Callable, Optional, TYPE_CHECKING, Type +from typing import Sequence, Tuple, List, Callable, Optional, TYPE_CHECKING, Type, Union from aiorpcx import run_in_thread, CancelledError @@ -78,7 +78,7 @@ import copy if TYPE_CHECKING: - from electrumx.lib.coins import AtomicalsCoin + from electrumx.lib.coins import Coin, AtomicalsCoinMixin from electrumx.server.env import Env from electrumx.server.controller import Notifications @@ -101,7 +101,7 @@ class Prefetcher: def __init__( self, daemon: 'Daemon', - coin: Type['AtomicalsCoin'], + coin: Type[Union['Coin', 'AtomicalsCoinMixin']], blocks_event: asyncio.Event, *, polling_delay_secs, diff --git a/electrumx/server/daemon.py b/electrumx/server/daemon.py index 13ffb32c..fc392a02 100644 --- a/electrumx/server/daemon.py +++ b/electrumx/server/daemon.py @@ -13,7 +13,7 @@ import time from calendar import timegm from struct import pack -from typing import TYPE_CHECKING, Type +from typing import TYPE_CHECKING, Type, Union import aiohttp from aiorpcx import JSONRPC @@ -25,7 +25,7 @@ unpack_le_uint16_from) if TYPE_CHECKING: - from electrumx.lib.coins import AtomicalsCoin + from electrumx.lib.coins import Coin, AtomicalsCoinMixin class DaemonError(Exception): @@ -48,7 +48,7 @@ class Daemon: def __init__( self, - coin: Type['AtomicalsCoin'], + coin: Type[Union['Coin', 'AtomicalsCoinMixin']], url, *, max_workqueue=10, @@ -307,12 +307,14 @@ async def height(self): '''Query the daemon for its current height.''' self._height = await self._send_single('getblockcount') return self._height + # return self.coin.ATOMICALS_ACTIVATION_HEIGHT - 1 def cached_height(self): '''Return the cached daemon height. If the daemon has not been queried yet this returns None.''' return self._height + # return self.coin.ATOMICALS_ACTIVATION_HEIGHT - 1 class DashDaemon(Daemon): diff --git a/electrumx/server/env.py b/electrumx/server/env.py index 25a46484..52d8e887 100644 --- a/electrumx/server/env.py +++ b/electrumx/server/env.py @@ -10,10 +10,10 @@ import re from ipaddress import IPv4Address, IPv6Address -from typing import Type +from typing import Type, Union from aiorpcx import Service, ServicePart -from electrumx.lib.coins import AtomicalsCoin +from electrumx.lib.coins import Coin, AtomicalsCoinMixin from electrumx.lib.env_base import EnvBase @@ -32,7 +32,7 @@ class Env(EnvBase): SSL_PROTOCOLS = {'ssl', 'wss'} KNOWN_PROTOCOLS = {'ssl', 'tcp', 'ws', 'wss', 'rpc', 'http'} - coin: Type[AtomicalsCoin] + coin: Type[Union['Coin', 'AtomicalsCoinMixin']] def __init__(self, coin=None): super().__init__() @@ -47,12 +47,12 @@ def __init__(self, coin=None): self.daemon_url = self.required('DAEMON_URL') self.daemon_proxy_url = self.default('DAEMON_PROXY_URL', None) if coin is not None: - assert issubclass(coin, AtomicalsCoin) + assert issubclass(coin, Coin) self.coin = coin else: coin_name = self.required('COIN').strip() network = self.default('NET', 'mainnet').strip() - self.coin = AtomicalsCoin.lookup_coin_class(coin_name, network) + self.coin = Coin.lookup_coin_class(coin_name, network) # Peer discovery diff --git a/electrumx/server/mempool.py b/electrumx/server/mempool.py index d4975e07..e2aed33a 100644 --- a/electrumx/server/mempool.py +++ b/electrumx/server/mempool.py @@ -12,7 +12,7 @@ from abc import ABC, abstractmethod from asyncio import Lock from collections import defaultdict -from typing import Sequence, Tuple, TYPE_CHECKING, Type, Dict +from typing import Sequence, Tuple, TYPE_CHECKING, Type, Dict, Union import math import attr @@ -27,7 +27,7 @@ from electrumx.lib.hash import hash_to_hex_str, HASHX_LEN, double_sha256 if TYPE_CHECKING: - from electrumx.lib.coins import AtomicalsCoin + from electrumx.lib.coins import Coin, AtomicalsCoinMixin @attr.s(slots=True) @@ -112,7 +112,7 @@ class MemPool: def __init__( self, - coin: Type['AtomicalsCoin'], + coin: Type[Union['Coin', 'AtomicalsCoinMixin']], api: MemPoolAPI, *, refresh_secs=5.0, diff --git a/tests/test_blocks.py b/tests/test_blocks.py index 3e75b889..5ee06baa 100644 --- a/tests/test_blocks.py +++ b/tests/test_blocks.py @@ -30,7 +30,7 @@ import pytest -from electrumx.lib.coins import AtomicalsCoin +from electrumx.lib.coins import Coin from electrumx.lib.hash import hex_str_to_hash BLOCKS_DIR = os.path.join( @@ -43,7 +43,7 @@ for name in os.listdir(BLOCKS_DIR): try: name_parts = name.split("_") - coin = AtomicalsCoin.lookup_coin_class(name_parts[0], name_parts[1]) + coin = Coin.lookup_coin_class(name_parts[0], name_parts[1]) with open(os.path.join(BLOCKS_DIR, name)) as f: blocks.append((coin, json.load(f))) except Exception as e: diff --git a/tests/test_transactions.py b/tests/test_transactions.py index 32164daf..ad709435 100644 --- a/tests/test_transactions.py +++ b/tests/test_transactions.py @@ -11,7 +11,7 @@ import pytest -from electrumx.lib.coins import AtomicalsCoin, Namecoin +from electrumx.lib.coins import Coin, Namecoin from electrumx.lib.hash import hash_to_hex_str from electrumx.lib.script import OpCodes, Script @@ -25,7 +25,7 @@ for name in os.listdir(TRANSACTION_DIR): try: name_parts = name.split("_") - coinFound = AtomicalsCoin.lookup_coin_class(name_parts[0], name_parts[1]) + coinFound = Coin.lookup_coin_class(name_parts[0], name_parts[1]) with open(os.path.join(TRANSACTION_DIR, name)) as f: transactions.append((coinFound, json.load(f))) except Exception as e: @@ -74,4 +74,4 @@ def test_transaction(transaction_details): normalized_name_op_script.append(OpCodes.OP_2DROP) normalized_name_op_script.append(OpCodes.OP_DROP) normalized_name_op_script.append(OpCodes.OP_RETURN) - assert coin.name_hashX_from_script(tx_pks) == AtomicalsCoin.hashX_from_script(normalized_name_op_script) + assert coin.name_hashX_from_script(tx_pks) == Coin.hashX_from_script(normalized_name_op_script)