diff --git a/hathor/builder/builder.py b/hathor/builder/builder.py index 0afa982a3d..62b2cd9e97 100644 --- a/hathor/builder/builder.py +++ b/hathor/builder/builder.py @@ -103,7 +103,7 @@ class BuildArtifacts(NamedTuple): tx_storage: TransactionStorage feature_service: FeatureService bit_signaling_service: BitSignalingService - indexes: Optional[IndexesManager] + indexes: IndexesManager wallet: Optional[BaseWallet] rocksdb_storage: RocksDBStorage stratum_factory: Optional[StratumFactory] diff --git a/hathor/builder/resources_builder.py b/hathor/builder/resources_builder.py index 23ee34fc28..7c5dde482f 100644 --- a/hathor/builder/resources_builder.py +++ b/hathor/builder/resources_builder.py @@ -315,7 +315,6 @@ def create_resources(self) -> server.Site: parent.putChild(url_path, resource) # Websocket resource - assert self.manager.tx_storage.indexes is not None ws_factory = HathorAdminWebsocketFactory(manager=self.manager, metrics=self.manager.metrics, address_index=self.manager.tx_storage.indexes.addresses) diff --git a/hathor/consensus/block_consensus.py b/hathor/consensus/block_consensus.py index a6b5b90bab..299e0384e8 100644 --- a/hathor/consensus/block_consensus.py +++ b/hathor/consensus/block_consensus.py @@ -267,7 +267,6 @@ def _nc_execute_calls(self, block: Block, *, is_reorg: bool) -> None: # Update indexes. This must be after metadata is updated. assert tx.storage is not None - assert tx.storage.indexes is not None tx.storage.indexes.handle_contract_execution(tx) # Pubsub event to indicate execution success @@ -413,9 +412,7 @@ def update_voided_info(self, block: Block) -> None: return assert block.storage is not None - storage = block.storage - assert storage.indexes is not None # Union of voided_by of parents voided_by: set[bytes] = self.union_voided_by_from_parents(block) @@ -517,7 +514,6 @@ def mark_as_reorg_if_needed(self, common_block: Block, new_best_block: Block) -> """Mark as reorg only if reorg size > 0.""" assert new_best_block.storage is not None storage = new_best_block.storage - assert storage.indexes is not None _, old_best_block_hash = storage.indexes.height.get_height_tip() old_best_block = storage.get_transaction(old_best_block_hash) assert isinstance(old_best_block, Block) @@ -745,7 +741,6 @@ def remove_first_block_markers(self, block: Block) -> None: if tx.is_nano_contract(): if meta.nc_execution == NCExecutionState.SUCCESS: assert tx.storage is not None - assert tx.storage.indexes is not None tx.storage.indexes.handle_contract_unexecution(tx) meta.nc_execution = NCExecutionState.PENDING meta.nc_calls = None diff --git a/hathor/consensus/consensus.py b/hathor/consensus/consensus.py index 5eb9bf7b6f..3090da093e 100644 --- a/hathor/consensus/consensus.py +++ b/hathor/consensus/consensus.py @@ -123,7 +123,6 @@ def unsafe_update(self, base: BaseTransaction) -> None: assert base.storage is not None storage = base.storage - assert storage.indexes is not None best_height, best_tip = storage.indexes.height.get_height_tip() # This has to be called before the removal of vertices, otherwise this call may fail. @@ -139,8 +138,7 @@ def unsafe_update(self, base: BaseTransaction) -> None: # signal a mempool tips index update for all affected transactions, # because that index is used on _compute_vertices_that_became_invalid below. for tx_affected in _sorted_affected_txs(context.txs_affected): - if storage.indexes.mempool_tips is not None: - storage.indexes.mempool_tips.update(tx_affected) + storage.indexes.mempool_tips.update(tx_affected) txs_to_remove: list[BaseTransaction] = [] new_best_height, new_best_tip = storage.indexes.height.get_height_tip() @@ -192,7 +190,6 @@ def unsafe_update(self, base: BaseTransaction) -> None: # finally signal an index update for all affected transactions for tx_affected in _sorted_affected_txs(context.txs_affected): assert tx_affected.storage is not None - assert tx_affected.storage.indexes is not None tx_affected.storage.indexes.update(tx_affected) context.pubsub.publish(HathorEvents.CONSENSUS_TX_UPDATE, tx=tx_affected) @@ -335,8 +332,6 @@ def _compute_vertices_that_became_invalid( """This method will look for transactions in the mempool that have become invalid after a reorg.""" from hathor.transaction.storage.traversal import BFSTimestampWalk from hathor.transaction.validation_state import ValidationState - assert storage.indexes is not None - assert storage.indexes.mempool_tips is not None mempool_tips = list(storage.indexes.mempool_tips.iter(storage)) if not mempool_tips: diff --git a/hathor/indexes/manager.py b/hathor/indexes/manager.py index 2689c698db..506679409b 100644 --- a/hathor/indexes/manager.py +++ b/hathor/indexes/manager.py @@ -66,7 +66,7 @@ class IndexesManager(ABC): sorted_txs: TimestampIndex height: HeightIndex - mempool_tips: Optional[MempoolTipsIndex] + mempool_tips: MempoolTipsIndex addresses: Optional[AddressIndex] tokens: Optional[TokensIndex] utxo: Optional[UtxoIndex] @@ -120,22 +120,11 @@ def enable_utxo_index(self) -> None: """Enable UTXO index. It does nothing if it has already been enabled.""" raise NotImplementedError - @abstractmethod - def enable_mempool_index(self) -> None: - """Enable mempool index. It does nothing if it has already been enabled.""" - raise NotImplementedError - @abstractmethod def enable_nc_indexes(self) -> None: """Enable Nano Contract related indexes.""" raise NotImplementedError - def force_clear_all(self) -> None: - """ Force clear all indexes. - """ - for index in self.iter_all_indexes(): - index.force_clear() - def _manually_initialize(self, tx_storage: 'TransactionStorage') -> None: """ Initialize the indexes, checking the indexes that need initialization, and the optimal iterator to use. """ @@ -205,8 +194,7 @@ def _manually_initialize(self, tx_storage: 'TransactionStorage') -> None: def update(self, tx: BaseTransaction) -> None: """ This is the new update method that indexes should use instead of add_tx/del_tx """ - if self.mempool_tips: - self.mempool_tips.update(tx) + self.mempool_tips.update(tx) if self.utxo: self.utxo.update(tx) @@ -413,7 +401,7 @@ def del_tx(self, tx: BaseTransaction, *, remove_all: bool = False, relax_assert: self.info.update_counts(tx, remove=True) # mempool will pick-up if the transaction is voided/invalid and remove it - if self.mempool_tips is not None and tx.storage.transaction_exists(tx.hash): + if tx.storage.transaction_exists(tx.hash): logger.debug('remove from mempool tips', tx=tx.hash_hex) self.mempool_tips.update(tx, force_remove=True) @@ -428,6 +416,7 @@ def del_tx(self, tx: BaseTransaction, *, remove_all: bool = False, relax_assert: class RocksDBIndexesManager(IndexesManager): def __init__(self, rocksdb_storage: 'RocksDBStorage', *, settings: HathorSettings) -> None: + from hathor.indexes.memory_mempool_tips_index import MemoryMempoolTipsIndex from hathor.indexes.rocksdb_height_index import RocksDBHeightIndex from hathor.indexes.rocksdb_info_index import RocksDBInfoIndex from hathor.indexes.rocksdb_timestamp_index import RocksDBTimestampIndex @@ -437,6 +426,8 @@ def __init__(self, rocksdb_storage: 'RocksDBStorage', *, settings: HathorSetting self.info = RocksDBInfoIndex(self._db, settings=settings) self.height = RocksDBHeightIndex(self._db, settings=settings) + # XXX: use of RocksDBMempoolTipsIndex is very slow and was suspended + self.mempool_tips = MemoryMempoolTipsIndex(settings=self.settings) self.sorted_all = RocksDBTimestampIndex(self._db, scope_type=TimestampScopeType.ALL, settings=settings) self.sorted_blocks = RocksDBTimestampIndex(self._db, scope_type=TimestampScopeType.BLOCKS, settings=settings) @@ -445,7 +436,6 @@ def __init__(self, rocksdb_storage: 'RocksDBStorage', *, settings: HathorSetting self.addresses = None self.tokens = None self.utxo = None - self.mempool_tips = None self.nc_creation = None self.nc_history = None self.blueprints = None @@ -469,12 +459,6 @@ def enable_utxo_index(self) -> None: if self.utxo is None: self.utxo = RocksDBUtxoIndex(self._db, settings=self.settings) - def enable_mempool_index(self) -> None: - from hathor.indexes.memory_mempool_tips_index import MemoryMempoolTipsIndex - if self.mempool_tips is None: - # XXX: use of RocksDBMempoolTipsIndex is very slow and was suspended - self.mempool_tips = MemoryMempoolTipsIndex(settings=self.settings) - def enable_nc_indexes(self) -> None: from hathor.indexes.blueprint_timestamp_index import BlueprintTimestampIndex from hathor.indexes.rocksdb_blueprint_history_index import RocksDBBlueprintHistoryIndex diff --git a/hathor/manager.py b/hathor/manager.py index 82c66b8a86..98f166b36f 100644 --- a/hathor/manager.py +++ b/hathor/manager.py @@ -439,8 +439,6 @@ def _initialize_components(self) -> None: self.wallet._manually_initialize() self.tx_storage.pre_init() - assert self.tx_storage.indexes is not None - self._bit_signaling_service.start() started_at = int(time.time()) @@ -517,7 +515,6 @@ def _verify_checkpoints(self) -> None: This method needs the essential indexes to be already initialized. """ - assert self.tx_storage.indexes is not None # based on the current best-height, filter-out checkpoints that aren't expected to exist in the database best_height = self.tx_storage.get_height_best_block() expected_checkpoints = [cp for cp in self.checkpoints if cp.height <= best_height] diff --git a/hathor/nanocontracts/resources/history.py b/hathor/nanocontracts/resources/history.py index 19be828c41..01fd025445 100644 --- a/hathor/nanocontracts/resources/history.py +++ b/hathor/nanocontracts/resources/history.py @@ -43,7 +43,6 @@ def render_GET(self, request: 'Request') -> bytes: set_cors(request, 'GET') tx_storage = self.manager.tx_storage - assert tx_storage.indexes is not None if tx_storage.indexes.nc_history is None: request.setResponseCode(503) error_response = ErrorResponse(success=False, error='Nano contract history index not initialized') diff --git a/hathor/nanocontracts/resources/nc_creation.py b/hathor/nanocontracts/resources/nc_creation.py index 9eadea29ab..b9a8277c1a 100644 --- a/hathor/nanocontracts/resources/nc_creation.py +++ b/hathor/nanocontracts/resources/nc_creation.py @@ -38,7 +38,6 @@ def __init__(self, manager: HathorManager) -> None: super().__init__() self.manager = manager self.tx_storage = self.manager.tx_storage - assert self.tx_storage.indexes is not None self.nc_creation_index = self.tx_storage.indexes.nc_creation self.nc_history_index = self.tx_storage.indexes.nc_history self.bp_history_index = self.tx_storage.indexes.blueprint_history diff --git a/hathor/nanocontracts/resources/on_chain.py b/hathor/nanocontracts/resources/on_chain.py index 5de787a04a..689846b866 100644 --- a/hathor/nanocontracts/resources/on_chain.py +++ b/hathor/nanocontracts/resources/on_chain.py @@ -44,7 +44,6 @@ def render_GET(self, request: Request) -> bytes: set_cors(request, 'GET') tx_storage = self.manager.tx_storage - assert tx_storage.indexes is not None if tx_storage.indexes.blueprints is None: request.setResponseCode(503) error_response = ErrorResponse(success=False, error='Blueprint index not initialized') diff --git a/hathor/nanocontracts/resources/state.py b/hathor/nanocontracts/resources/state.py index 08f242e943..96696facbc 100644 --- a/hathor/nanocontracts/resources/state.py +++ b/hathor/nanocontracts/resources/state.py @@ -84,15 +84,6 @@ def render_GET(self, request: 'Request') -> bytes: if params.block_height is not None: # Get hash of the block with the height - if self.manager.tx_storage.indexes is None: - # No indexes enabled in the storage - request.setResponseCode(503) - error_response = ErrorResponse( - success=False, - error='No indexes enabled in the storage, so we can\'t filter by block height.' - ) - return error_response.json_dumpb() - block_hash = self.manager.tx_storage.indexes.height.get(params.block_height) if block_hash is None: # No block hash was found with this height @@ -103,15 +94,6 @@ def render_GET(self, request: 'Request') -> bytes: ) return error_response.json_dumpb() elif params.timestamp is not None: - if self.manager.tx_storage.indexes is None: - # No indexes enabled in the storage - request.setResponseCode(503) - error_response = ErrorResponse( - success=False, - error='No indexes enabled in the storage, so we can\'t filter by timestamp.' - ) - return error_response.json_dumpb() - block_hashes, has_more = self.manager.tx_storage.indexes.sorted_blocks.get_older( timestamp=params.timestamp, hash_bytes=None, diff --git a/hathor/p2p/manager.py b/hathor/p2p/manager.py index 422deb7ebc..44dacdcf0d 100644 --- a/hathor/p2p/manager.py +++ b/hathor/p2p/manager.py @@ -259,11 +259,6 @@ def set_manager(self, manager: 'HathorManager') -> None: raise TypeError('Class built incorrectly without any enabled sync version') self.manager = manager - if self.is_sync_version_available(SyncVersion.V2): - assert self.manager.tx_storage.indexes is not None - indexes = self.manager.tx_storage.indexes - self.log.debug('enable sync-v2 indexes') - indexes.enable_mempool_index() def add_listen_address_description(self, addr: str) -> None: """Add address to listen for incoming connections.""" diff --git a/hathor/p2p/sync_v2/agent.py b/hathor/p2p/sync_v2/agent.py index 27957d9e27..08f6f2ba99 100644 --- a/hathor/p2p/sync_v2/agent.py +++ b/hathor/p2p/sync_v2/agent.py @@ -181,8 +181,6 @@ def __init__( def get_status(self) -> dict[str, Any]: """ Return the status of the sync. """ - assert self.tx_storage.indexes is not None - assert self.tx_storage.indexes.mempool_tips is not None tips = self.tx_storage.indexes.mempool_tips.get() tips_limited, tips_has_more = collect_n(iter(tips), MAX_MEMPOOL_STATUS_TIPS) res = { @@ -361,7 +359,6 @@ def run_sync_blocks(self) -> Generator[Any, Any, bool]: Notice that we might already have all other peer's blocks while the other peer is still syncing. """ - assert self.tx_storage.indexes is not None self.state = PeerState.SYNCING_BLOCKS # Get my best block. @@ -462,8 +459,6 @@ def send_get_tips(self) -> None: def handle_get_tips(self, _payload: str) -> None: """ Handle a GET-TIPS message. """ - assert self.tx_storage.indexes is not None - assert self.tx_storage.indexes.mempool_tips is not None if self._is_streaming: self.log.warn('can\'t send while streaming') # XXX: or can we? self.send_message(ProtocolMessages.MEMPOOL_END) @@ -641,7 +636,6 @@ def send_get_peer_block_hashes(self, heights: list[int]) -> None: def handle_get_peer_block_hashes(self, payload: str) -> None: """ Handle a GET-PEER-BLOCK-HASHES message. """ - assert self.tx_storage.indexes is not None heights = json.loads(payload) if len(heights) > 20: self.log.info('too many heights', heights_qty=len(heights)) diff --git a/hathor/transaction/resources/block_at_height.py b/hathor/transaction/resources/block_at_height.py index 9d6577ded2..60dd4f0621 100644 --- a/hathor/transaction/resources/block_at_height.py +++ b/hathor/transaction/resources/block_at_height.py @@ -44,8 +44,6 @@ def render_GET(self, request: 'Request') -> bytes: :rtype: string (json) """ - assert self.manager.tx_storage.indexes is not None - request.setHeader(b'content-type', b'application/json; charset=utf-8') set_cors(request, 'GET') diff --git a/hathor/transaction/resources/mempool.py b/hathor/transaction/resources/mempool.py index 0328032a9d..bd2e6059c2 100644 --- a/hathor/transaction/resources/mempool.py +++ b/hathor/transaction/resources/mempool.py @@ -85,12 +85,8 @@ def render_GET(self, request: 'Request') -> bytes: return json_dumpb(data) def _get_from_index(self, index_source: IndexSource) -> Iterator[Transaction]: - tx_storage = self.manager.tx_storage - assert tx_storage.indexes is not None if index_source == IndexSource.ANY or index_source == IndexSource.MEMPOOL: - # XXX: if source is ANY we try to use the mempool when possible - if tx_storage.indexes.mempool_tips is None: - raise ValueError('mempool index is not enabled') + # XXX: if source is ANY we try to use the mempool yield from self._get_from_mempool_tips_index() elif index_source == IndexSource.TX_TIPS: raise ValueError('tx-tips index has been removed') @@ -99,8 +95,6 @@ def _get_from_index(self, index_source: IndexSource) -> Iterator[Transaction]: def _get_from_mempool_tips_index(self) -> Iterator[Transaction]: tx_storage = self.manager.tx_storage - assert tx_storage.indexes is not None - assert tx_storage.indexes.mempool_tips is not None yield from tx_storage.indexes.mempool_tips.iter_all(tx_storage) diff --git a/hathor/transaction/resources/transaction.py b/hathor/transaction/resources/transaction.py index 6f22a44379..cc46c07f83 100644 --- a/hathor/transaction/resources/transaction.py +++ b/hathor/transaction/resources/transaction.py @@ -58,8 +58,6 @@ def get_tx_extra_data( Returns success, tx serializes, metadata and spent outputs """ assert tx.storage is not None - assert tx.storage.indexes is not None - settings = get_global_settings() serialized = tx.to_json(decode_script=True) serialized['raw'] = tx.get_struct().hex() diff --git a/hathor/transaction/resources/utxo_search.py b/hathor/transaction/resources/utxo_search.py index 51d04e3124..32a4dad140 100644 --- a/hathor/transaction/resources/utxo_search.py +++ b/hathor/transaction/resources/utxo_search.py @@ -62,7 +62,6 @@ def render_GET(self, request: 'Request') -> bytes: # setup tx_storage = self.manager.tx_storage - assert tx_storage.indexes is not None if tx_storage.indexes.utxo is None: request.setResponseCode(503) return json_dumpb({'success': False}) diff --git a/hathor/transaction/storage/rocksdb_storage.py b/hathor/transaction/storage/rocksdb_storage.py index 182f3fbc4a..b280ad750e 100644 --- a/hathor/transaction/storage/rocksdb_storage.py +++ b/hathor/transaction/storage/rocksdb_storage.py @@ -61,11 +61,11 @@ def __init__( *, reactor: ReactorProtocol, rocksdb_storage: RocksDBStorage, - indexes: Optional[IndexesManager] = None, settings: 'HathorSettings', vertex_parser: VertexParser, nc_storage_factory: NCStorageFactory, vertex_children_service: RocksDBVertexChildrenService, + indexes: IndexesManager, cache_config: CacheConfig | None = None, ) -> None: self._reactor = reactor diff --git a/hathor/transaction/storage/transaction_storage.py b/hathor/transaction/storage/transaction_storage.py index 7d845571f2..d942ec5631 100644 --- a/hathor/transaction/storage/transaction_storage.py +++ b/hathor/transaction/storage/transaction_storage.py @@ -93,7 +93,7 @@ class TransactionStorage(ABC): """Legacy sync interface, please copy @deprecated decorator when implementing methods.""" pubsub: Optional[PubSubManager] - indexes: Optional[IndexesManager] + indexes: IndexesManager _latest_n_height_tips: list[HeightInfo] nc_catalog: Optional['NCBlueprintCatalog'] = None @@ -128,10 +128,12 @@ def __init__( settings: HathorSettings, nc_storage_factory: NCStorageFactory, vertex_children_service: VertexChildrenService, + indexes: IndexesManager, ) -> None: self._settings = settings self._nc_storage_factory = nc_storage_factory self.vertex_children = vertex_children_service + self.indexes = indexes # Weakref is used to guarantee that there is only one instance of each transaction in memory. self._tx_weakref: WeakValueDictionary[bytes, BaseTransaction] = WeakValueDictionary() self._tx_weakref_disabled: bool = False @@ -161,8 +163,6 @@ def __init__( # Internal toggle to choose when to select topological DFS iterator, used only on some tests self._always_use_topological_dfs = False - self._saving_genesis = False - # Migrations instances self._migrations = [cls() for cls in self._migration_factories] @@ -184,11 +184,6 @@ def get_allow_scope(self) -> TxAllowScope: """Get the current allow scope.""" return self._allow_scope - @abstractmethod - def reset_indexes(self) -> None: - """Reset all the indexes, making sure that no persisted value is reused.""" - raise NotImplementedError - @abstractmethod def is_empty(self) -> bool: """True when only genesis is present, useful for checking for a fresh database.""" @@ -329,7 +324,6 @@ def _checked_set_network(self, network: str) -> None: def get_best_block(self) -> Block: """The block with highest score or one of the blocks with highest scores. Can be used for mining.""" - assert self.indexes is not None block_hash = self.indexes.height.get_tip() block = self.get_transaction(block_hash) assert isinstance(block, Block) @@ -338,7 +332,6 @@ def get_best_block(self) -> Block: def _save_or_verify_genesis(self) -> None: """Save all genesis in the storage.""" - self._saving_genesis = True genesis_txs = [ self._construct_genesis_block(), self._construct_genesis_tx1(), @@ -355,7 +348,6 @@ def _save_or_verify_genesis(self) -> None: self.add_to_indexes(tx) tx2 = tx self._genesis_cache[tx2.hash] = tx2 - self._saving_genesis = False def _save_to_weakref(self, tx: BaseTransaction) -> None: """ Save transaction to weakref. @@ -490,8 +482,7 @@ def remove_transaction(self, tx: BaseTransaction) -> None: :param tx: Transaction to be removed """ - if self.indexes is not None: - self.del_from_indexes(tx, remove_all=True, relax_assert=True) + self.del_from_indexes(tx, remove_all=True, relax_assert=True) @abstractmethod def transaction_exists(self, hash_bytes: bytes) -> bool: @@ -583,7 +574,6 @@ def get_token_creation_transaction(self, hash_bytes: bytes) -> TokenCreationTran def get_block_by_height(self, height: int) -> Optional[Block]: """Return a block in the best blockchain from the height index. This is fast.""" - assert self.indexes is not None ancestor_hash = self.indexes.height.get(height) return None if ancestor_hash is None else self.get_block(ancestor_hash) @@ -635,12 +625,10 @@ def first_timestamp(self) -> int: raise NotImplementedError def get_best_block_hash(self) -> VertexId: - assert self.indexes is not None return VertexId(self.indexes.height.get_tip()) @abstractmethod def get_n_height_tips(self, n_blocks: int) -> list[HeightInfo]: - assert self.indexes is not None return self.indexes.height.get_n_height_tips(n_blocks) def get_weight_best_block(self) -> float: @@ -649,7 +637,6 @@ def get_weight_best_block(self) -> float: def get_height_best_block(self) -> int: """ Iterate over best block tips and get the highest height """ - assert self.indexes is not None block_info = self.indexes.height.get_height_tip() return block_info.height @@ -738,8 +725,6 @@ def topological_iterator(self) -> Iterator[BaseTransaction]: # is known to be true, but we could add a mechanism similar to what indexes use to know they're # up-to-date and get rid of that assumption so this method can be used without having to make any # assumptions - assert self.indexes is not None - if self._always_use_topological_dfs: self.log.debug('force choosing DFS iterator') return self._topological_sort_dfs() @@ -918,7 +903,6 @@ def update_last_started_at(self, timestamp: int) -> None: Using this mehtod ensures that the same timestamp is being used and the correct indexes are being selected. """ - assert self.indexes is not None self.set_last_started_at(timestamp) for index in self.indexes.iter_all_indexes(): index_db_name = index.get_db_name() @@ -936,14 +920,10 @@ def flush(self) -> None: def iter_mempool_tips(self) -> Iterator[Transaction]: """Get tx tips in the mempool, using the mempool-tips index""" - assert self.indexes is not None - assert self.indexes.mempool_tips is not None yield from self.indexes.mempool_tips.iter(self) def iter_mempool(self) -> Iterator[Transaction]: """Get all transactions in the mempool, using the mempool-tips index""" - assert self.indexes is not None - assert self.indexes.mempool_tips is not None yield from self.indexes.mempool_tips.iter_all(self) def _construct_genesis_block(self) -> Block: @@ -1113,29 +1093,25 @@ def migrate_vertex_children(self) -> None: class BaseTransactionStorage(TransactionStorage): - indexes: Optional[IndexesManager] - def __init__( self, - indexes: Optional[IndexesManager] = None, pubsub: Optional[Any] = None, *, settings: HathorSettings, nc_storage_factory: NCStorageFactory, vertex_children_service: VertexChildrenService, + indexes: IndexesManager, ) -> None: super().__init__( settings=settings, nc_storage_factory=nc_storage_factory, vertex_children_service=vertex_children_service, + indexes=indexes, ) # Pubsub is used to publish tx voided and winner but it's optional self.pubsub = pubsub - # Indexes. - self.indexes = indexes - # Either save or verify all genesis. self._save_or_verify_genesis() @@ -1143,19 +1119,12 @@ def __init__( @property def latest_timestamp(self) -> int: - assert self.indexes is not None return self.indexes.info.get_latest_timestamp() @property def first_timestamp(self) -> int: - assert self.indexes is not None return self.indexes.info.get_first_timestamp() - def reset_indexes(self) -> None: - """Reset all indexes. This function should not be called unless you know what you are doing.""" - assert self.indexes is not None, 'Cannot reset indexes because they have not been enabled.' - self.indexes.force_clear_all() - def get_n_height_tips(self, n_blocks: int) -> list[HeightInfo]: block = self.get_best_block() if self._latest_n_height_tips: @@ -1170,50 +1139,32 @@ def get_weight_best_block(self) -> float: return super().get_weight_best_block() def get_newest_blocks(self, count: int) -> tuple[list[Block], bool]: - if self.indexes is None: - raise NotImplementedError - assert self.indexes is not None block_hashes, has_more = self.indexes.sorted_blocks.get_newest(count) blocks = [cast(Block, self.get_transaction(block_hash)) for block_hash in block_hashes] return blocks, has_more def get_newest_txs(self, count: int) -> tuple[list[BaseTransaction], bool]: - if self.indexes is None: - raise NotImplementedError - assert self.indexes is not None tx_hashes, has_more = self.indexes.sorted_txs.get_newest(count) txs = [self.get_transaction(tx_hash) for tx_hash in tx_hashes] return txs, has_more def get_older_blocks_after(self, timestamp: int, hash_bytes: bytes, count: int) -> tuple[list[Block], bool]: - if self.indexes is None: - raise NotImplementedError - assert self.indexes is not None block_hashes, has_more = self.indexes.sorted_blocks.get_older(timestamp, hash_bytes, count) blocks = [cast(Block, self.get_transaction(block_hash)) for block_hash in block_hashes] return blocks, has_more def get_newer_blocks_after(self, timestamp: int, hash_bytes: bytes, count: int) -> tuple[list[BaseTransaction], bool]: - if self.indexes is None: - raise NotImplementedError - assert self.indexes is not None block_hashes, has_more = self.indexes.sorted_blocks.get_newer(timestamp, hash_bytes, count) blocks = [self.get_transaction(block_hash) for block_hash in block_hashes] return blocks, has_more def get_older_txs_after(self, timestamp: int, hash_bytes: bytes, count: int) -> tuple[list[BaseTransaction], bool]: - if self.indexes is None: - raise NotImplementedError - assert self.indexes is not None tx_hashes, has_more = self.indexes.sorted_txs.get_older(timestamp, hash_bytes, count) txs = [self.get_transaction(tx_hash) for tx_hash in tx_hashes] return txs, has_more def get_newer_txs_after(self, timestamp: int, hash_bytes: bytes, count: int) -> tuple[list[BaseTransaction], bool]: - if self.indexes is None: - raise NotImplementedError - assert self.indexes is not None tx_hashes, has_more = self.indexes.sorted_txs.get_newer(timestamp, hash_bytes, count) txs = [self.get_transaction(tx_hash) for tx_hash in tx_hashes] return txs, has_more @@ -1222,12 +1173,9 @@ def _manually_initialize(self) -> None: self._manually_initialize_indexes() def _manually_initialize_indexes(self) -> None: - if self.indexes is not None: - self.indexes._manually_initialize(self) + self.indexes._manually_initialize(self) def _topological_sort_timestamp_index(self) -> Iterator[BaseTransaction]: - assert self.indexes is not None - cur_timestamp: Optional[int] = None cur_blocks: list[Block] = [] cur_txs: list[Transaction] = [] @@ -1337,38 +1285,18 @@ def _run_topological_sort_dfs(self, root: BaseTransaction, visited: dict[bytes, stack.append(txinput) def add_to_indexes(self, tx: BaseTransaction) -> None: - if self.indexes is None: - if self._saving_genesis: - # XXX: avoid failing on some situations where this is called before we know it's OK to skip - # see: https://github.com/HathorNetwork/hathor-core/pull/436 - return - else: - raise NotImplementedError - assert self.indexes is not None self.indexes.add_tx(tx) def del_from_indexes(self, tx: BaseTransaction, *, remove_all: bool = False, relax_assert: bool = False) -> None: - if self.indexes is None: - raise NotImplementedError - assert self.indexes is not None self.indexes.del_tx(tx, remove_all=remove_all, relax_assert=relax_assert) def get_block_count(self) -> int: - if self.indexes is None: - raise NotImplementedError - assert self.indexes is not None return self.indexes.info.get_block_count() def get_tx_count(self) -> int: - if self.indexes is None: - raise NotImplementedError - assert self.indexes is not None return self.indexes.info.get_tx_count() def get_vertices_count(self) -> int: - if self.indexes is None: - raise NotImplementedError - assert self.indexes is not None return self.indexes.info.get_vertices_count() def get_genesis(self, hash_bytes: bytes) -> Optional[BaseTransaction]: diff --git a/hathor/vertex_handler/vertex_handler.py b/hathor/vertex_handler/vertex_handler.py index 2b6839a03d..36887e61ec 100644 --- a/hathor/vertex_handler/vertex_handler.py +++ b/hathor/vertex_handler/vertex_handler.py @@ -254,7 +254,6 @@ def _post_consensus( """ # XXX: during post consensus we don't need to verify weights again, so we can disable it params = replace(params, skip_block_weight_verification=True) - assert self._tx_storage.indexes is not None assert self._verification_service.validate_full( vertex, params, diff --git a/hathor/websocket/iterators.py b/hathor/websocket/iterators.py index 41f6e72984..14cf2e4c1e 100644 --- a/hathor/websocket/iterators.py +++ b/hathor/websocket/iterators.py @@ -130,7 +130,6 @@ async def gap_limit_search( ) -> AddressSearch: """An async iterator that yields addresses and vertices, stopping when the gap limit is reached. """ - assert manager.tx_storage.indexes is not None assert manager.tx_storage.indexes.addresses is not None addresses_index = manager.tx_storage.indexes.addresses empty_addresses_counter = 0 diff --git a/hathor_cli/builder.py b/hathor_cli/builder.py index 9879492dd4..f9c38e9446 100644 --- a/hathor_cli/builder.py +++ b/hathor_cli/builder.py @@ -215,15 +215,15 @@ def create_manager(self, reactor: Reactor) -> HathorManager: execution_manager=execution_manager, ) - if self._args.wallet_index and tx_storage.indexes is not None: + if self._args.wallet_index: self.log.debug('enable wallet indexes') self.enable_wallet_index(tx_storage.indexes, pubsub) - if self._args.utxo_index and tx_storage.indexes is not None: + if self._args.utxo_index: self.log.debug('enable utxo index') tx_storage.indexes.enable_utxo_index() - if self._args.nc_indexes and tx_storage.indexes is not None: + if self._args.nc_indexes: self.log.debug('enable nano indexes') tx_storage.indexes.enable_nc_indexes() diff --git a/hathor_tests/feature_activation/test_feature_service.py b/hathor_tests/feature_activation/test_feature_service.py index 188e8733a4..636b20b635 100644 --- a/hathor_tests/feature_activation/test_feature_service.py +++ b/hathor_tests/feature_activation/test_feature_service.py @@ -39,7 +39,7 @@ def get_storage(settings: HathorSettings, *, up_to_height: int) -> TransactionStorage: artifacts = TestBuilder(settings).build() storage = artifacts.tx_storage - indexes = not_none(artifacts.indexes) + indexes = artifacts.indexes feature_activation_bits = [ 0b0000, # 0: boundary block 0b0010, diff --git a/hathor_tests/nanocontracts/test_actions.py b/hathor_tests/nanocontracts/test_actions.py index 485beabe5d..77a602d99a 100644 --- a/hathor_tests/nanocontracts/test_actions.py +++ b/hathor_tests/nanocontracts/test_actions.py @@ -83,7 +83,6 @@ def setUp(self) -> None: self.manager.tx_storage.nc_catalog = NCBlueprintCatalog({ self.bp_id: MyBlueprint }) - assert self.manager.tx_storage.indexes is not None self.tokens_index: TokensIndex = not_none(self.manager.tx_storage.indexes.tokens) self.nc_seqnum = 0 diff --git a/hathor_tests/nanocontracts/test_indexes2.py b/hathor_tests/nanocontracts/test_indexes2.py index f12aeaaac4..c865fa10d1 100644 --- a/hathor_tests/nanocontracts/test_indexes2.py +++ b/hathor_tests/nanocontracts/test_indexes2.py @@ -31,8 +31,6 @@ def initialize(self, ctx: Context, amount: int) -> None: class TestIndexes2(BlueprintTestCase): def setUp(self) -> None: super().setUp() - - assert self.manager.tx_storage.indexes is not None assert self.manager.tx_storage.indexes.tokens is not None self.tokens_index = self.manager.tx_storage.indexes.tokens diff --git a/hathor_tests/others/test_init_manager.py b/hathor_tests/others/test_init_manager.py index 619303d493..7022322982 100644 --- a/hathor_tests/others/test_init_manager.py +++ b/hathor_tests/others/test_init_manager.py @@ -1,6 +1,7 @@ from typing import Iterator from hathor.conf.settings import HathorSettings +from hathor.indexes import RocksDBIndexesManager from hathor.pubsub import PubSubManager from hathor.reactor import ReactorProtocol from hathor.simulator.utils import add_new_block, add_new_blocks @@ -19,6 +20,7 @@ def __init__(self, reactor: ReactorProtocol, path: str, settings: HathorSettings from hathor.nanocontracts.storage import NCRocksDBStorageFactory rocksdb_storage = RocksDBStorage(path=path) nc_storage_factory = NCRocksDBStorageFactory(rocksdb_storage) + indexes = RocksDBIndexesManager(rocksdb_storage=rocksdb_storage, settings=settings) super().__init__( reactor=reactor, rocksdb_storage=rocksdb_storage, @@ -26,6 +28,7 @@ def __init__(self, reactor: ReactorProtocol, path: str, settings: HathorSettings vertex_parser=VertexParser(settings=settings), nc_storage_factory=nc_storage_factory, vertex_children_service=RocksDBVertexChildrenService(rocksdb_storage), + indexes=indexes, ) self._first_tx: BaseTransaction | None = None diff --git a/hathor_tests/others/test_metrics.py b/hathor_tests/others/test_metrics.py index 8e8db8f9bb..8c0e0e1b20 100644 --- a/hathor_tests/others/test_metrics.py +++ b/hathor_tests/others/test_metrics.py @@ -1,6 +1,7 @@ import tempfile from unittest.mock import Mock +from hathor.indexes import RocksDBIndexesManager from hathor.manager import HathorManager from hathor.p2p.manager import PeerConnectionsMetrics from hathor.p2p.peer import PrivatePeer @@ -257,6 +258,7 @@ def test_cache_data_collection(self): rocksdb_storage = self.create_rocksdb_storage() nc_storage_factory = NCRocksDBStorageFactory(rocksdb_storage) vertex_children_service = RocksDBVertexChildrenService(rocksdb_storage) + indexes = RocksDBIndexesManager(rocksdb_storage=rocksdb_storage, settings=self._settings) tx_storage = TransactionRocksDBStorage( reactor=self.reactor, rocksdb_storage=rocksdb_storage, @@ -264,6 +266,7 @@ def test_cache_data_collection(self): vertex_parser=VertexParser(settings=self._settings), nc_storage_factory=nc_storage_factory, vertex_children_service=vertex_children_service, + indexes=indexes, cache_config=CacheConfig(), ) diff --git a/hathor_tests/p2p/test_double_spending.py b/hathor_tests/p2p/test_double_spending.py index 1b5e9bb99f..a61d01a2d8 100644 --- a/hathor_tests/p2p/test_double_spending.py +++ b/hathor_tests/p2p/test_double_spending.py @@ -86,7 +86,6 @@ def test_simple_double_spending(self) -> None: spent_meta = spent_tx.get_metadata() self.assertEqual([tx1.hash, tx2.hash], spent_meta.spent_outputs[txin.index]) - assert self.manager1.tx_storage.indexes.mempool_tips is not None self.assertNotIn(tx1.hash, self.manager1.tx_storage.indexes.mempool_tips.get()) self.assertNotIn(tx2.hash, self.manager1.tx_storage.indexes.mempool_tips.get()) @@ -111,7 +110,6 @@ def test_simple_double_spending(self) -> None: spent_meta = spent_tx.get_metadata() self.assertEqual([tx1.hash, tx2.hash, tx3.hash], spent_meta.spent_outputs[txin.index]) - assert self.manager1.tx_storage.indexes.mempool_tips is not None self.assertNotIn(tx1.hash, self.manager1.tx_storage.indexes.mempool_tips.get()) self.assertNotIn(tx2.hash, self.manager1.tx_storage.indexes.mempool_tips.get()) self.assertIn(tx3.hash, self.manager1.tx_storage.indexes.mempool_tips.get()) diff --git a/hathor_tests/p2p/test_split_brain.py b/hathor_tests/p2p/test_split_brain.py index a7550d4568..9919ce656e 100644 --- a/hathor_tests/p2p/test_split_brain.py +++ b/hathor_tests/p2p/test_split_brain.py @@ -134,7 +134,7 @@ def test_split_brain_only_blocks_different_height(self) -> None: # Add one more block to manager1, so it's the winner chain add_new_block(manager1, advance_clock=1) - block_tip1 = not_none(manager1.tx_storage.indexes).height.get_tip() + block_tip1 = manager1.tx_storage.indexes.height.get_tip() self.assertConsensusValid(manager1) self.assertConsensusValid(manager2) @@ -157,8 +157,8 @@ def test_split_brain_only_blocks_different_height(self) -> None: self.assertConsensusValid(manager2) self.assertConsensusEqual(manager1, manager2) - self.assertEqual(block_tip1, not_none(manager1.tx_storage.indexes).height.get_tip()) - self.assertEqual(block_tip1, not_none(manager2.tx_storage.indexes).height.get_tip()) + self.assertEqual(block_tip1, manager1.tx_storage.indexes.height.get_tip()) + self.assertEqual(block_tip1, manager2.tx_storage.indexes.height.get_tip()) def test_split_brain_only_blocks_same_height(self) -> None: manager1 = self.create_peer(self.network, unlock_wallet=True) diff --git a/hathor_tests/p2p/test_sync_v2.py b/hathor_tests/p2p/test_sync_v2.py index 86a7dc88ba..4cf23dd861 100644 --- a/hathor_tests/p2p/test_sync_v2.py +++ b/hathor_tests/p2p/test_sync_v2.py @@ -244,8 +244,6 @@ def test_receiving_tips_limit(self) -> None: ''') artifacts.propagate_with(manager1) - assert manager1.tx_storage.indexes is not None - assert manager1.tx_storage.indexes.mempool_tips is not None mempool_tips_count = len(manager1.tx_storage.indexes.mempool_tips.get()) # we should expect at the very least 30 tips self.assertGreater(mempool_tips_count, 30) @@ -381,7 +379,7 @@ def fake_get_peer_block_hashes(heights: list[int]) -> Deferred[list[_HeightInfo] response = [] for h in heights: if h < reorg_height: - index_manager = not_none(conn12.manager2.tx_storage.indexes) + index_manager = conn12.manager2.tx_storage.indexes vertex_id = not_none(index_manager.height.get(h)) else: vertex_id = rng.randbytes(32) @@ -416,7 +414,7 @@ def fake_get_peer_block_hashes(heights: list[int]) -> Deferred[list[_HeightInfo] response = [] for h in heights: if h < reorg_height: - index_manager = not_none(conn12.manager2.tx_storage.indexes) + index_manager = conn12.manager2.tx_storage.indexes vertex_id = not_none(index_manager.height.get(h)) else: vertex_id = rng.randbytes(32) diff --git a/hathor_tests/tx/test_block.py b/hathor_tests/tx/test_block.py index a4e99d55c6..2462466eea 100644 --- a/hathor_tests/tx/test_block.py +++ b/hathor_tests/tx/test_block.py @@ -43,7 +43,7 @@ def test_calculate_feature_activation_bit_counts_genesis(): def tx_storage() -> TransactionStorage: artifacts = TestBuilder().build() storage = artifacts.tx_storage - indexes = not_none(artifacts.indexes) + indexes = artifacts.indexes feature_activation_bits = [ 0b0000, # 0: boundary block 0b1010, diff --git a/hathor_tests/tx/test_indexes.py b/hathor_tests/tx/test_indexes.py index bc10468a1a..b93cafd337 100644 --- a/hathor_tests/tx/test_indexes.py +++ b/hathor_tests/tx/test_indexes.py @@ -1,5 +1,6 @@ from hathor.crypto.util import decode_address from hathor.graphviz import GraphvizVisualizer +from hathor.indexes import RocksDBIndexesManager from hathor.simulator.utils import add_new_block, add_new_blocks from hathor.storage.rocksdb_storage import RocksDBStorage from hathor.transaction import Transaction @@ -31,11 +32,10 @@ def test_tx_tips_with_conflict(self): tx1.timestamp = int(self.clock.seconds()) self.manager.cpu_mining_service.resolve(tx1) self.assertTrue(self.manager.propagate_tx(tx1)) - if self.manager.tx_storage.indexes.mempool_tips is not None: - self.assertEqual( - {tx.hash for tx in self.manager.tx_storage.indexes.mempool_tips.iter(self.manager.tx_storage)}, - {tx1.hash} - ) + self.assertEqual( + {tx.hash for tx in self.manager.tx_storage.indexes.mempool_tips.iter(self.manager.tx_storage)}, + {tx1.hash} + ) outputs = [WalletOutputInfo(address=decode_address(address), value=value, timelock=None)] @@ -46,11 +46,10 @@ def test_tx_tips_with_conflict(self): tx2.timestamp = int(self.clock.seconds()) + 1 self.manager.cpu_mining_service.resolve(tx2) self.assertTrue(self.manager.propagate_tx(tx2)) - if self.manager.tx_storage.indexes.mempool_tips is not None: - self.assertEqual( - {tx.hash for tx in self.manager.tx_storage.indexes.mempool_tips.iter(self.manager.tx_storage)}, - {tx2.hash} - ) + self.assertEqual( + {tx.hash for tx in self.manager.tx_storage.indexes.mempool_tips.iter(self.manager.tx_storage)}, + {tx2.hash} + ) tx3 = Transaction.create_from_struct(tx2.get_struct()) tx3.timestamp = tx2.timestamp + 1 @@ -59,14 +58,13 @@ def test_tx_tips_with_conflict(self): self.assertNotEqual(tx2.hash, tx3.hash) self.assertTrue(self.manager.propagate_tx(tx3)) self.assertIn(tx3.hash, tx2.get_metadata().conflict_with) - if self.manager.tx_storage.indexes.mempool_tips is not None: - self.assertEqual( - {tx.hash for tx in self.manager.tx_storage.indexes.mempool_tips.iter(self.manager.tx_storage)}, - # XXX: what should we expect here? I don't think we should exclude both tx2 and tx3, but maybe let the - # function using the index decide - # {tx1.hash, tx3.hash} - {tx1.hash} - ) + self.assertEqual( + {tx.hash for tx in self.manager.tx_storage.indexes.mempool_tips.iter(self.manager.tx_storage)}, + # XXX: what should we expect here? I don't think we should exclude both tx2 and tx3, but maybe let the + # function using the index decide + # {tx1.hash, tx3.hash} + {tx1.hash} + ) def test_tx_tips_voided(self): from hathor.wallet.base_wallet import WalletOutputInfo @@ -88,11 +86,10 @@ def test_tx_tips_voided(self): tx1.timestamp = int(self.clock.seconds()) self.manager.cpu_mining_service.resolve(tx1) self.assertTrue(self.manager.propagate_tx(tx1)) - if self.manager.tx_storage.indexes.mempool_tips is not None: - self.assertEqual( - {tx.hash for tx in self.manager.tx_storage.indexes.mempool_tips.iter(self.manager.tx_storage)}, - {tx1.hash} - ) + self.assertEqual( + {tx.hash for tx in self.manager.tx_storage.indexes.mempool_tips.iter(self.manager.tx_storage)}, + {tx1.hash} + ) tx2 = self.manager.wallet.prepare_transaction_compute_inputs(Transaction, outputs, self.manager.tx_storage) tx2.weight = 2.0 @@ -101,11 +98,10 @@ def test_tx_tips_voided(self): tx2.timestamp = int(self.clock.seconds()) + 1 self.manager.cpu_mining_service.resolve(tx2) self.assertTrue(self.manager.propagate_tx(tx2)) - if self.manager.tx_storage.indexes.mempool_tips is not None: - self.assertEqual( - {tx.hash for tx in self.manager.tx_storage.indexes.mempool_tips.iter(self.manager.tx_storage)}, - {tx2.hash} - ) + self.assertEqual( + {tx.hash for tx in self.manager.tx_storage.indexes.mempool_tips.iter(self.manager.tx_storage)}, + {tx2.hash} + ) tx3 = Transaction.create_from_struct(tx2.get_struct()) tx3.weight = 3.0 @@ -117,13 +113,12 @@ def test_tx_tips_voided(self): self.assertTrue(self.manager.propagate_tx(tx3)) # self.assertIn(tx3.hash, tx2.get_metadata().voided_by) self.assertIn(tx3.hash, tx2.get_metadata().conflict_with) - if self.manager.tx_storage.indexes.mempool_tips is not None: - self.assertEqual( - {tx.hash for tx in self.manager.tx_storage.indexes.mempool_tips.iter(self.manager.tx_storage)}, - # XXX: what should we expect here? I don't think we should exclude both tx2 and tx3, but maybe let the - # function using the index decide - {tx1.hash, tx3.hash} - ) + self.assertEqual( + {tx.hash for tx in self.manager.tx_storage.indexes.mempool_tips.iter(self.manager.tx_storage)}, + # XXX: what should we expect here? I don't think we should exclude both tx2 and tx3, but maybe let the + # function using the index decide + {tx1.hash, tx3.hash} + ) def test_genesis_not_in_mempool(self): mempool_txs = list(self.tx_storage.indexes.mempool_tips.iter_all(self.tx_storage)) @@ -135,8 +130,6 @@ def test_utxo_index_genesis(self): from hathor_tests.utils import GENESIS_ADDRESS_B58 HTR_UID = self._settings.HATHOR_TOKEN_UID - - assert self.tx_storage.indexes is not None utxo_index = self.tx_storage.indexes.utxo # let's check everything is alright, all UTXOs should currently be from just the mined blocks and genesis @@ -177,8 +170,6 @@ def test_utxo_index_genesis(self): def test_utxo_index_reorg(self): from hathor.indexes.utxo_index import UtxoIndexItem - - assert self.tx_storage.indexes is not None utxo_index = self.tx_storage.indexes.utxo add_new_blocks(self.manager, 5, advance_clock=15) @@ -276,8 +267,6 @@ def check_utxos(*args): def test_utxo_index_simple(self): from hathor.indexes.utxo_index import UtxoIndexItem - - assert self.tx_storage.indexes is not None utxo_index = self.tx_storage.indexes.utxo address = self.get_address(0) @@ -357,8 +346,6 @@ def test_utxo_index_limits(self): from hathor.indexes.utxo_index import UtxoIndexItem _debug = False - - assert self.tx_storage.indexes is not None utxo_index = self.tx_storage.indexes.utxo address = self.get_address(0) @@ -437,8 +424,6 @@ def test_utxo_index_after_push_tx(self): from hathor.indexes.utxo_index import UtxoIndexItem from hathor.transaction import TxInput, TxOutput from hathor.transaction.scripts import P2PKH - - assert self.tx_storage.indexes is not None utxo_index = self.tx_storage.indexes.utxo address = self.get_address(0) @@ -509,8 +494,6 @@ def test_utxo_index_last(self): from hathor.indexes.utxo_index import UtxoIndexItem from hathor.transaction import TxInput, TxOutput from hathor.transaction.scripts import P2PKH - - assert self.tx_storage.indexes is not None utxo_index = self.tx_storage.indexes.utxo address = self.get_address(0) @@ -702,6 +685,7 @@ def setUp(self): parser = VertexParser(settings=self._settings) nc_storage_factory = NCRocksDBStorageFactory(rocksdb_storage) vertex_children_service = RocksDBVertexChildrenService(rocksdb_storage) + indexes = RocksDBIndexesManager(rocksdb_storage=rocksdb_storage, settings=self._settings) self.tx_storage = TransactionRocksDBStorage( reactor=self.reactor, rocksdb_storage=rocksdb_storage, @@ -709,6 +693,7 @@ def setUp(self): vertex_parser=parser, nc_storage_factory=nc_storage_factory, vertex_children_service=vertex_children_service, + indexes=indexes, ) self.genesis = self.tx_storage.get_all_genesis() self.genesis_blocks = [tx for tx in self.genesis if tx.is_block] diff --git a/hathor_tests/tx/test_indexes4.py b/hathor_tests/tx/test_indexes4.py index 0548fb2c6f..1e8383753c 100644 --- a/hathor_tests/tx/test_indexes4.py +++ b/hathor_tests/tx/test_indexes4.py @@ -56,7 +56,6 @@ def test_index_initialization(self): # XXX: this test makes use of the internals of TipsIndex, AddressIndex and UtxoIndex tx_storage = self.manager.tx_storage - assert tx_storage.indexes is not None # XXX: sanity check that we've at least produced something self.assertGreater(tx_storage.get_vertices_count(), 3) diff --git a/hathor_tests/tx/test_indexes_nc_history.py b/hathor_tests/tx/test_indexes_nc_history.py index 847c693834..97e0cf1561 100644 --- a/hathor_tests/tx/test_indexes_nc_history.py +++ b/hathor_tests/tx/test_indexes_nc_history.py @@ -1,5 +1,6 @@ from hathor.conf import HathorSettings from hathor.crypto.util import get_address_b58_from_bytes +from hathor.indexes import RocksDBIndexesManager from hathor.nanocontracts import Blueprint, Context, public from hathor.nanocontracts.catalog import NCBlueprintCatalog from hathor.nanocontracts.utils import sign_openssl @@ -114,7 +115,7 @@ def test_transaction_count(self) -> None: manager = self.create_peer_from_builder(builder) assert isinstance(manager.tx_storage, TransactionRocksDBStorage) path = manager.tx_storage._rocksdb_storage.path - indexes_manager = not_none(manager.tx_storage.indexes) + indexes_manager = manager.tx_storage.indexes nc_history_index = not_none(indexes_manager.nc_history) private_key = unittest.OCB_TEST_PRIVKEY.hex() password = unittest.OCB_TEST_PASSWORD.hex() @@ -174,7 +175,7 @@ def test_transaction_count(self) -> None: # Test loading counts from existing db builder2 = self.get_builder().set_rocksdb_path(path).enable_nc_indexes() manager2 = self.create_peer_from_builder(builder2) - indexes_manager2 = not_none(manager2.tx_storage.indexes) + indexes_manager2 = manager2.tx_storage.indexes nc_history_index = not_none(indexes_manager2.nc_history) assert nc_history_index.get_transaction_count(nc1.hash) == 3 @@ -199,6 +200,7 @@ def setUp(self): vertex_parser = VertexParser(settings=self._settings) nc_storage_factory = NCRocksDBStorageFactory(rocksdb_storage) vertex_children_service = RocksDBVertexChildrenService(rocksdb_storage) + indexes = RocksDBIndexesManager(rocksdb_storage=rocksdb_storage, settings=settings) self.tx_storage = TransactionRocksDBStorage( reactor=self.reactor, rocksdb_storage=rocksdb_storage, @@ -206,6 +208,7 @@ def setUp(self): vertex_parser=vertex_parser, nc_storage_factory=nc_storage_factory, vertex_children_service=vertex_children_service, + indexes=indexes, ) self.genesis = self.tx_storage.get_all_genesis() self.genesis_blocks = [tx for tx in self.genesis if tx.is_block] diff --git a/hathor_tests/tx/test_mempool_tips_index.py b/hathor_tests/tx/test_mempool_tips_index.py index fff713f1ea..576e708cf5 100644 --- a/hathor_tests/tx/test_mempool_tips_index.py +++ b/hathor_tests/tx/test_mempool_tips_index.py @@ -30,8 +30,6 @@ def setUp(self) -> None: self.manager = self.create_peer_from_builder(builder) self.tx_storage = self.manager.tx_storage - assert self.tx_storage.indexes is not None - assert self.tx_storage.indexes.mempool_tips is not None self.mempool_tips = self.tx_storage.indexes.mempool_tips self.dag_builder = TestDAGBuilder.from_manager(self.manager) diff --git a/hathor_tests/tx/test_tips.py b/hathor_tests/tx/test_tips.py index 21d2110aa0..d4c3eae220 100644 --- a/hathor_tests/tx/test_tips.py +++ b/hathor_tests/tx/test_tips.py @@ -14,8 +14,6 @@ def setUp(self): self.manager = self.create_peer(self.network, unlock_wallet=True) def get_tips(self): - assert self.manager.tx_storage.indexes is not None - assert self.manager.tx_storage.indexes.mempool_tips is not None return self.manager.tx_storage.indexes.mempool_tips.get() def test_tips_back(self): diff --git a/hathor_tests/tx/test_tx_storage.py b/hathor_tests/tx/test_tx_storage.py index 5d1d43c236..f55cab04d8 100644 --- a/hathor_tests/tx/test_tx_storage.py +++ b/hathor_tests/tx/test_tx_storage.py @@ -169,31 +169,28 @@ def validate_save(self, obj): idx_elem = (obj.timestamp, obj.hash) # Testing add and remove from cache - if self.tx_storage.indexes is not None: - self.assertIn(idx_elem, self.tx_storage.indexes.sorted_all) - if obj.is_block: - self.assertIn(idx_elem, self.tx_storage.indexes.sorted_blocks) - self.assertNotIn(idx_elem, self.tx_storage.indexes.sorted_txs) - else: - self.assertIn(idx_elem, self.tx_storage.indexes.sorted_txs) - self.assertNotIn(idx_elem, self.tx_storage.indexes.sorted_blocks) + self.assertIn(idx_elem, self.tx_storage.indexes.sorted_all) + if obj.is_block: + self.assertIn(idx_elem, self.tx_storage.indexes.sorted_blocks) + self.assertNotIn(idx_elem, self.tx_storage.indexes.sorted_txs) + else: + self.assertIn(idx_elem, self.tx_storage.indexes.sorted_txs) + self.assertNotIn(idx_elem, self.tx_storage.indexes.sorted_blocks) self.tx_storage.del_from_indexes(obj, remove_all=True) - if self.tx_storage.indexes is not None: - self.assertNotIn(idx_elem, self.tx_storage.indexes.sorted_all) - self.assertNotIn(idx_elem, self.tx_storage.indexes.sorted_txs) - self.assertNotIn(idx_elem, self.tx_storage.indexes.sorted_blocks) + self.assertNotIn(idx_elem, self.tx_storage.indexes.sorted_all) + self.assertNotIn(idx_elem, self.tx_storage.indexes.sorted_txs) + self.assertNotIn(idx_elem, self.tx_storage.indexes.sorted_blocks) self.tx_storage.add_to_indexes(obj) - if self.tx_storage.indexes is not None: - self.assertIn(idx_elem, self.tx_storage.indexes.sorted_all) - if obj.is_block: - self.assertIn(idx_elem, self.tx_storage.indexes.sorted_blocks) - self.assertNotIn(idx_elem, self.tx_storage.indexes.sorted_txs) - else: - self.assertIn(idx_elem, self.tx_storage.indexes.sorted_txs) - self.assertNotIn(idx_elem, self.tx_storage.indexes.sorted_blocks) + self.assertIn(idx_elem, self.tx_storage.indexes.sorted_all) + if obj.is_block: + self.assertIn(idx_elem, self.tx_storage.indexes.sorted_blocks) + self.assertNotIn(idx_elem, self.tx_storage.indexes.sorted_txs) + else: + self.assertIn(idx_elem, self.tx_storage.indexes.sorted_txs) + self.assertNotIn(idx_elem, self.tx_storage.indexes.sorted_blocks) def test_save_block(self): self.validate_save(self.block) diff --git a/hathor_tests/tx/test_verification_mempool.py b/hathor_tests/tx/test_verification_mempool.py index 8f795792d1..f7019dd20e 100644 --- a/hathor_tests/tx/test_verification_mempool.py +++ b/hathor_tests/tx/test_verification_mempool.py @@ -223,7 +223,6 @@ def test_conflict_with_confirmed_nc_fail_is_allowed(self) -> None: assert self.manager.vertex_handler.on_new_mempool_transaction(tx_ok) assert self.manager.tx_storage.transaction_exists(tx_ok.hash) - assert self.manager.tx_storage.indexes.mempool_tips is not None mempool_hashes = { tx.hash for tx in self.manager.tx_storage.indexes.mempool_tips.iter_all(self.manager.tx_storage) } @@ -283,7 +282,6 @@ def test_mempool_tx_returns_after_reorg_with_confirmed_nc_fail_conflict(self) -> assert self.manager.vertex_handler.on_new_mempool_transaction(tx_ok) - assert self.manager.tx_storage.indexes.mempool_tips is not None mempool_hashes = { tx.hash for tx in self.manager.tx_storage.indexes.mempool_tips.iter_all(self.manager.tx_storage) } diff --git a/hathor_tests/unittest.py b/hathor_tests/unittest.py index 2e61426356..cf4138a50c 100644 --- a/hathor_tests/unittest.py +++ b/hathor_tests/unittest.py @@ -309,10 +309,10 @@ def assertTipsNotEqual(self, manager1: HathorManager, manager2: HathorManager) - This method assert that something should not match, either the tx-tips or the block-tip. """ - tips1 = not_none(not_none(manager1.tx_storage.indexes).mempool_tips).get() - tips1 |= {not_none(manager1.tx_storage.indexes).height.get_tip()} - tips2 = not_none(not_none(manager2.tx_storage.indexes).mempool_tips).get() - tips2 |= {not_none(manager2.tx_storage.indexes).height.get_tip()} + tips1 = manager1.tx_storage.indexes.mempool_tips.get() + tips1 |= {manager1.tx_storage.indexes.height.get_tip()} + tips2 = manager2.tx_storage.indexes.mempool_tips.get() + tips2 |= {manager2.tx_storage.indexes.height.get_tip()} self.assertNotEqual(tips1, tips2) def assertTipsEqualSyncV2( @@ -324,8 +324,8 @@ def assertTipsEqualSyncV2( ) -> None: # tx tips if strict_sync_v2_indexes: - tips1 = not_none(not_none(manager1.tx_storage.indexes).mempool_tips).get() - tips2 = not_none(not_none(manager2.tx_storage.indexes).mempool_tips).get() + tips1 = manager1.tx_storage.indexes.mempool_tips.get() + tips2 = manager2.tx_storage.indexes.mempool_tips.get() else: tips1 = {tx.hash for tx in manager1.tx_storage.iter_mempool_tips()} tips2 = {tx.hash for tx in manager2.tx_storage.iter_mempool_tips()} @@ -341,8 +341,8 @@ def assertTipsEqualSyncV2( self.assertEqual(s1, s2) # best block (from height index) - b1 = not_none(manager1.tx_storage.indexes).height.get_tip() - b2 = not_none(manager2.tx_storage.indexes).height.get_tip() + b1 = manager1.tx_storage.indexes.height.get_tip() + b2 = manager2.tx_storage.indexes.height.get_tip() self.assertIn(b1, s2) self.assertIn(b2, s1)