def setUp(self, tx_storage, reactor=None): if not reactor: self.reactor = Clock() else: self.reactor = reactor self.reactor.advance(time.time()) self.tx_storage = tx_storage assert tx_storage.first_timestamp > 0 tx_storage._manually_initialize() self.genesis = self.tx_storage.get_all_genesis() self.genesis_blocks = [tx for tx in self.genesis if tx.is_block] self.genesis_txs = [tx for tx in self.genesis if not tx.is_block] from hathor.manager import HathorManager self.tmpdir = tempfile.mkdtemp() wallet = Wallet(directory=self.tmpdir) wallet.unlock(b'teste') self.manager = HathorManager(self.reactor, tx_storage=self.tx_storage, wallet=wallet) self.tx_storage.wallet_index = WalletIndex(self.manager.pubsub) self.tx_storage.tokens_index = TokensIndex() block_parents = [tx.hash for tx in chain(self.genesis_blocks, self.genesis_txs)] output = TxOutput(200, bytes.fromhex('1e393a5ce2ff1c98d4ff6892f2175100f2dad049')) self.block = Block(timestamp=MIN_TIMESTAMP, weight=12, outputs=[output], parents=block_parents, nonce=100781, storage=tx_storage) self.block.resolve() self.block.verify() tx_parents = [tx.hash for tx in self.genesis_txs] tx_input = TxInput( tx_id=self.genesis_blocks[0].hash, index=0, data=bytes.fromhex('46304402203470cb9818c9eb842b0c433b7e2b8aded0a51f5903e971649e870763d0266a' 'd2022049b48e09e718c4b66a0f3178ef92e4d60ee333d2d0e25af8868acf5acbb35aaa583' '056301006072a8648ce3d020106052b8104000a034200042ce7b94cba00b654d4308f8840' '7345cacb1f1032fb5ac80407b74d56ed82fb36467cb7048f79b90b1cf721de57e942c5748' '620e78362cf2d908e9057ac235a63')) self.tx = Transaction( timestamp=MIN_TIMESTAMP + 2, weight=10, nonce=932049, inputs=[tx_input], outputs=[output], tokens=[bytes.fromhex('0023be91834c973d6a6ddd1a0ae411807b7c8ef2a015afb5177ee64b666ce602')], parents=tx_parents, storage=tx_storage) self.tx.resolve() # Disable weakref to test the internal methods. Otherwise, most methods return objects from weakref. self.tx_storage._disable_weakref() self.tx_storage.enable_lock()
def __init__(self, reactor: IReactorCore, peer_id: Optional[PeerId] = None, network: Optional[str] = None, hostname: Optional[str] = None, pubsub: Optional[PubSubManager] = None, wallet: Optional[BaseWallet] = None, tx_storage: Optional[TransactionStorage] = None, peer_storage: Optional[Any] = None, default_port: int = 40403, wallet_index: bool = False, stratum_port: Optional[int] = None, min_block_weight: Optional[int] = None, ssl: bool = True) -> None: """ :param reactor: Twisted reactor which handles the mainloop and the events. :param peer_id: Id of this node. If not given, a new one is created. :param network: Name of the network this node participates. Usually it is either testnet or mainnet. :type network: string :param hostname: The hostname of this node. It is used to generate its entrypoints. :type hostname: string :param pubsub: If not given, a new one is created. :type pubsub: :py:class:`hathor.pubsub.PubSubManager` :param tx_storage: If not given, a :py:class:`TransactionMemoryStorage` one is created. :type tx_storage: :py:class:`hathor.transaction.storage.transaction_storage.TransactionStorage` :param peer_storage: If not given, a new one is created. :type peer_storage: :py:class:`hathor.p2p.peer_storage.PeerStorage` :param default_port: Network default port. It is used when only ip addresses are discovered. :type default_port: int :param wallet_index: If should add a wallet index in the storage :type wallet_index: bool :param stratum_port: Stratum server port. Stratum server will only be created if it is not None. :type stratum_port: Optional[int] :param min_block_weight: Minimum weight for blocks. :type min_block_weight: Optional[int] """ from hathor.p2p.factory import HathorServerFactory, HathorClientFactory from hathor.p2p.manager import ConnectionsManager from hathor.transaction.storage.memory_storage import TransactionMemoryStorage from hathor.metrics import Metrics self.log = logger.new() self.reactor = reactor if hasattr(self.reactor, 'addSystemEventTrigger'): self.reactor.addSystemEventTrigger('after', 'shutdown', self.stop) self.state: Optional[HathorManager.NodeState] = None self.profiler: Optional[Any] = None # Hostname, used to be accessed by other peers. self.hostname = hostname # Remote address, which can be different from local address. self.remote_address = None self.my_peer = peer_id or PeerId() self.network = network or 'testnet' # XXX Should we use a singleton or a new PeerStorage? [msbrogli 2018-08-29] self.pubsub = pubsub or PubSubManager(self.reactor) self.tx_storage = tx_storage or TransactionMemoryStorage() self.tx_storage.pubsub = self.pubsub if wallet_index and self.tx_storage.with_index: self.tx_storage.wallet_index = WalletIndex(self.pubsub) self.tx_storage.tokens_index = TokensIndex() self.avg_time_between_blocks = settings.AVG_TIME_BETWEEN_BLOCKS self.min_block_weight = min_block_weight or settings.MIN_BLOCK_WEIGHT self.min_tx_weight = settings.MIN_TX_WEIGHT self.metrics = Metrics( pubsub=self.pubsub, avg_time_between_blocks=self.avg_time_between_blocks, tx_storage=tx_storage, reactor=self.reactor, ) self.consensus_algorithm = ConsensusAlgorithm() self.peer_discoveries: List[PeerDiscovery] = [] self.ssl = ssl self.server_factory = HathorServerFactory(self.network, self.my_peer, node=self, use_ssl=ssl) self.client_factory = HathorClientFactory(self.network, self.my_peer, node=self, use_ssl=ssl) self.connections = ConnectionsManager(self.reactor, self.my_peer, self.server_factory, self.client_factory, self.pubsub, self, ssl) self.wallet = wallet if self.wallet: self.wallet.pubsub = self.pubsub self.wallet.reactor = self.reactor # When manager is in test mode we reduce the weight of blocks/transactions. self.test_mode: int = 0 # Multiplier coefficient to adjust the minimum weight of a normal tx to 18 self.min_tx_weight_coefficient = 1.6 # Amount in which tx min weight reaches the middle point between the minimum and maximum weight. self.min_tx_weight_k = 100 self.stratum_factory = StratumFactory( manager=self, port=stratum_port) if stratum_port else None # Set stratum factory for metrics object self.metrics.stratum_factory = self.stratum_factory self._allow_mining_without_peers = False # Thread pool used to resolve pow when sending tokens self.pow_thread_pool = ThreadPool(minthreads=0, maxthreads=settings.MAX_POW_THREADS, name='Pow thread pool') # List of addresses to listen for new connections (eg: [tcp:8000]) self.listen_addresses: List[str] = []
def _count_empty(addresses: Set[str], wallet_index: WalletIndex) -> int: """ Count how many of the addresses given are empty (have no outputs).""" return sum(1 for addr in addresses if not wallet_index.get_from_address(addr))