def add_node(self,
                 node_id: int,
                 peers: List[int] = None,
                 params: List[str] = None,
                 log_levels: Dict[str, str] = None,
                 private: bool = True,
                 config_client: bool = True,
                 use_tls: Tuple[str, str] = None,
                 snapshot: str = None,
                 branch: str = "") -> None:
        """ Launches new node with given node_id and initializes client

        Args:
            node_id (int): id of the node, defines its RPC/P2P port and serves
                           as an identifier for client and deamons
            peer (list): id of peers initialized trusted by this nodes
            params (list): list of additional parameters to run the node
            log_levels (dict): log levels. e.g. {"p2p.connection-pool":"debug"}
            private (bool): enable private mode, default=True
            config_client (bool): initialize client with sandbox identities,
                                  default=True
            use_tls (list): couple of filenames containing
                           (tezos.crt, tezos.k), default=None
            snapshot (str): import snapshot  before initializing node
            branch (str): sub-dir where to lookup the node and client
                          binary, default = "". Allows execution of different
                          versions of nodes.

        This launches a node with default sandbox parameters

        tezos-node run
           --data-dir TMP_DIR
           --no-bootstrap-peers
           --sandbox=SANDBOX_FILE
           --peer TRUSTED_PEER_1 ... --peer TRUSTED_PEER_n #
           --private-mode # if private is True
           --connections 3 # overriden by params if not None
        """
        assert node_id not in self.nodes, f'Already a node for id={node_id}'
        rpc_node = self.rpc + node_id
        p2p_node = self.p2p + node_id
        assert 0 <= node_id < self.num_peers, f'{node_id} outside bounds'
        if peers is None:
            peers = list(range(self.num_peers))
        else:
            assert all(0 <= peer < self.num_peers for peer in peers)

        log_file = None
        if self.log_dir:
            log_file = f'{self.log_dir}/node{node_id}_{self.counter}.txt'
            self.logs.append(log_file)
            self.counter += 1

        if params is None:
            # TODO this option is confusing as it sets several parameters at
            # once
            params = ['--connections', '3']
        if private:
            params = params + ['--private-mode']
        peers_rpc = [self.p2p + p for p in peers]
        node_bin = self._wrap_path(NODE, branch)
        local_admin_client = self._wrap_path(CLIENT_ADMIN, branch)
        local_client = self._wrap_path(CLIENT, branch)
        node = Node(node_bin,
                    self.sandbox_file,
                    p2p_port=p2p_node,
                    rpc_port=rpc_node,
                    peers=peers_rpc,
                    log_file=log_file,
                    params=params,
                    log_levels=log_levels,
                    use_tls=use_tls)
        if snapshot is None:
            node.init_id()
            node.init_config()
        else:
            assert os.path.isfile(snapshot)
            node.snapshot_import(snapshot)
            node.init_id()
            node.init_config()
        node.run()
        client = Client(local_client,
                        local_admin_client,
                        rpc_port=rpc_node,
                        use_tls=bool(use_tls))
        time.sleep(0.1)
        # make sure node didn't fail at startup
        assert node.poll() is None, 'Seems node failed at startup'

        # don't wait for confirmation
        client.run(['-w', 'none', 'config', 'update'])
        if config_client:
            for name, iden in self.identities.items():
                client.import_secret_key(name, iden['secret'])
        self.nodes[node_id] = node
        self.clients[node_id] = client
Beispiel #2
0
    def add_node(self,
                 node_id: int,
                 peers: List[int] = None,
                 params: List[str] = None,
                 log_levels: Dict[str, str] = None,
                 private: bool = True,
                 config_client: bool = True,
                 use_tls: Tuple[str, str] = None,
                 snapshot: str = None,
                 reconstruct: bool = False,
                 branch: str = "",
                 client_factory: Callable = Client) -> None:
        """ Launches new node with given node_id and initializes client

        Args:
            node_id (int): id of the node, defines its RPC/P2P port and serves
                           as an identifier for client and daemons
            peer (list): id of peers initialized trusted by this nodes
            params (list): list of additional parameters to run the node
            log_levels (dict): log levels. e.g. {"p2p.connection-pool":"debug"}
            private (bool): enable private mode, default=True
            config_client (bool): initialize client with sandbox identities,
                                  default=True
            use_tls (Tuple[str, str]): couple of filenames containing
                           (tezos.crt, tezos.k), default=None
            snapshot (str): import snapshot  before initializing node
            branch (str): sub-dir where to lookup the node and client
                          binary, default = "". Allows execution of different
                          versions of nodes.
            client_factory (Callable): the constructor of clients. Defaults to
                                       Client. Allows e.g. regression testing.

        This launches a node with default sandbox parameters

        tezos-node run
           --data-dir TMP_DIR
           --no-bootstrap-peers
           --sandbox=SANDBOX_FILE
           --peer TRUSTED_PEER_1 ... --peer TRUSTED_PEER_n #
           --private-mode # if private is True
        """
        assert node_id not in self.nodes, f'Already a node for id={node_id}'
        rpc_node = self.rpc + node_id
        p2p_node = self.p2p + node_id
        assert 0 <= node_id < self.num_peers, f'{node_id} outside bounds'
        if peers is None:
            peers = list(range(self.num_peers))
        assert all(0 <= peer < self.num_peers for peer in peers)

        log_file = None
        if self.log_dir:
            log_file = f'{self.log_dir}/node{node_id}_{self.counter}.txt'
            self.logs.append(log_file)
            self.counter += 1

        params = [] if params is None else params
        if private:
            params = params + ['--private-mode']
        params = params + ['--network=sandbox']
        peers_rpc = [self.p2p + p for p in peers]
        node_bin = self._wrap_path(NODE, branch)
        local_admin_client = self._wrap_path(CLIENT_ADMIN, branch)
        local_client = self._wrap_path(CLIENT, branch)
        node = Node(node_bin,
                    self.sandbox_file,
                    p2p_port=p2p_node,
                    rpc_port=rpc_node,
                    peers=peers_rpc,
                    log_file=log_file,
                    params=params,
                    log_levels=log_levels,
                    use_tls=use_tls)
        if snapshot is None:
            node.init_id()
            node.init_config()
        else:
            assert os.path.isfile(snapshot)
            assert_msg = "The attribute sandbox_file can not be None. " \
                "Please verify you wrapped the call to this method inside a " \
                "with statement"
            assert self.sandbox_file is not None, assert_msg
            node.init_id()
            node.init_config()
            sandboxed_import = [f'--sandbox', self.sandbox_file]
            if reconstruct:
                node.snapshot_import(snapshot,
                                     ['--reconstruct', '--network=sandbox'] +
                                     sandboxed_import)
            else:
                node.snapshot_import(snapshot,
                                     ['--network=sandbox'] + sandboxed_import)
        node.run()
        client = client_factory(local_client,
                                local_admin_client,
                                rpc_port=rpc_node,
                                use_tls=bool(use_tls))

        if not client.check_node_listening():
            assert node.poll() is None, '# Node {node_id} failed at startup'
            node.kill()
            assert False, f"# Node {node_id} isn't responding to RPC"

        # don't wait for confirmation
        client.run(['-w', 'none', 'config', 'update'])
        if config_client:
            for name, iden in self.identities.items():
                client.import_secret_key(name, iden['secret'])
        self.nodes[node_id] = node
        self.clients[node_id] = client