def setUp(self):
     super().setUp()
     self.manager = self.create_peer('testnet')
     self.manager.allow_mining_without_peers()
     self.factory = StratumFactory(self.manager, port=8123, reactor=MemoryReactorClock())
     self.factory.start()
     self.protocol = self.factory.buildProtocol('127.0.0.1')
     self.transport = StringTransportWithDisconnection()
     self.transport.protocol = self.protocol
     self.protocol.makeConnection(self.transport)
Beispiel #2
0
 def setUp(self):
     super().setUp()
     self.manager = self.create_peer('testnet')
     self.manager.allow_mining_without_peers()
     self.factory = StratumFactory(self.manager,
                                   port=8123,
                                   reactor=MemoryReactorClock())
     self.factory.start()
     self.protocol = self.factory.buildProtocol('127.0.0.1')
     self.transport = StringTransportWithDisconnection()
     self.transport.protocol = self.protocol
     self.protocol.makeConnection(self.transport)
     # subscribe and ignore response
     _send_subscribe(self.protocol)
     self.job = self._get_latest_message()['params']
     self.transport.clear()
Beispiel #3
0
    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] = []
Beispiel #4
0
    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,
                 ssl: bool = True,
                 enable_sync_v1: bool = True,
                 enable_sync_v2: bool = False,
                 capabilities: Optional[List[str]] = None,
                 checkpoints: Optional[List[Checkpoint]] = None,
                 rng: Optional[Random] = None,
                 soft_voided_tx_ids: Optional[Set[bytes]] = None) -> 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: Required storage backend.
        :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]
        """
        from hathor.metrics import Metrics
        from hathor.p2p.factory import HathorClientFactory, HathorServerFactory
        from hathor.p2p.manager import ConnectionsManager

        if not (enable_sync_v1 or enable_sync_v2):
            raise TypeError(
                f'{type(self).__name__}() at least one sync version is required'
            )

        if tx_storage is None:
            raise TypeError(
                f'{type(self).__name__}() missing 1 required positional argument: \'tx_storage\''
            )

        self.log = logger.new()

        if rng is None:
            rng = Random()
        self.rng = rng

        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'

        self.is_started: bool = False

        self.cpu = cpu

        # XXX: first checkpoint must be genesis (height=0)
        self.checkpoints: List[Checkpoint] = checkpoints or []
        self.checkpoints_ready: List[bool] = [False] * len(self.checkpoints)
        if not self.checkpoints or self.checkpoints[0].height > 0:
            self.checkpoints.insert(0,
                                    Checkpoint(0, settings.GENESIS_BLOCK_HASH))
            self.checkpoints_ready.insert(0, True)
        else:
            self.checkpoints_ready[0] = True

        # 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
        self.tx_storage.pubsub = self.pubsub
        if wallet_index and self.tx_storage.with_index:
            assert self.tx_storage.indexes is not None
            self.log.debug('enable wallet indexes')
            self.tx_storage.indexes.enable_address_index(self.pubsub)
            self.tx_storage.indexes.enable_tokens_index()

        self.metrics = Metrics(
            pubsub=self.pubsub,
            avg_time_between_blocks=settings.AVG_TIME_BETWEEN_BLOCKS,
            tx_storage=self.tx_storage,
            reactor=self.reactor,
        )

        self.soft_voided_tx_ids = soft_voided_tx_ids or set()
        self.consensus_algorithm = ConsensusAlgorithm(self.soft_voided_tx_ids)

        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,
                                              whitelist_only=False,
                                              rng=self.rng,
                                              enable_sync_v1=enable_sync_v1,
                                              enable_sync_v2=enable_sync_v2)

        self.wallet = wallet
        if self.wallet:
            self.wallet.pubsub = self.pubsub
            self.wallet.reactor = self.reactor

        if stratum_port:
            # XXX: only import if needed
            from hathor.stratum import StratumFactory
            self.stratum_factory: Optional[StratumFactory] = StratumFactory(
                manager=self, port=stratum_port)
        else:
            self.stratum_factory = 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] = []

        # Full verification execute all validations for transactions and blocks when initializing the node
        # Can be activated on the command line with --full-verification
        self._full_verification = False

        # List of whitelisted peers
        self.peers_whitelist: List[str] = []

        # List of capabilities of the peer
        if capabilities is not None:
            self.capabilities = capabilities
        else:
            self.capabilities = DEFAULT_CAPABILITIES