Beispiel #1
0
    def setup_class(cls):
        """Set up the class."""
        super().setup_class()

        cls.expected_path_1 = os.path.abspath("path_1")
        cls.expected_path_2 = os.path.abspath("path_2")
        cls.cert_id_1 = "cert_id_1"
        cls.cert_id_2 = "cert_id_2"
        cls.cert_request_1 = CertRequest(
            identifier=cls.cert_id_1,
            ledger_id=FETCHAI,
            not_after="2020-01-02",
            not_before="2020-01-01",
            public_key=FETCHAI,
            save_path=cls.expected_path_1,
        )
        cls.cert_request_2 = CertRequest(
            identifier=cls.cert_id_2,
            ledger_id=FETCHAI,
            not_after="2020-01-02",
            not_before="2020-01-01",
            public_key="0xABCDEF123456",
            save_path=cls.expected_path_2,
        )
        cls.add_cert_requests(
            [cls.cert_request_1, cls.cert_request_2], DummyConnection.connection_id.name
        )

        # add fetchai key and connection key
        shutil.copy(
            FETCHAI_PRIVATE_KEY_PATH,
            os.path.join(cls.current_agent_context, FETCHAI_PRIVATE_KEY_FILE),
        )
        cls.add_private_key()
        cls.add_private_key(connection=True)
Beispiel #2
0
def test_agent_record(change_directory):
    """Test signature and public key proper retrieval from a CertRequest"""
    agent_key_1 = make_crypto(DEFAULT_LEDGER)
    agent_key_2 = make_crypto(DEFAULT_LEDGER)

    peer_public_key_1 = make_crypto(DEFAULT_LEDGER).public_key
    peer_public_key_2 = make_crypto(DEFAULT_LEDGER).public_key

    cert_path = "test_acn_cert.txt"

    cert = CertRequest(
        peer_public_key_1,
        "test_service",
        DEFAULT_LEDGER,
        "2021-01-01",
        "2022-01-01",
        cert_path,
    )
    _process_cert(agent_key_1, cert, change_directory)

    # success
    agent_record = AgentRecord.from_cert_request(cert, agent_key_1.address,
                                                 peer_public_key_1)
    assert (agent_record.address == agent_key_1.address
            and agent_record.public_key == agent_key_1.public_key
            and agent_record.representative_public_key == peer_public_key_1
            and agent_record.signature == cert.get_signature()
            and agent_record.message == cert.get_message(peer_public_key_1))

    # success
    agent_record = AgentRecord(
        agent_key_1.address,
        peer_public_key_1,
        cert.get_message(peer_public_key_1),
        cert.get_signature(),
        DEFAULT_LEDGER,
    )
    assert (agent_record.address == agent_key_1.address
            and agent_record.public_key == agent_key_1.public_key
            and agent_record.representative_public_key == peer_public_key_1
            and agent_record.signature == cert.get_signature()
            and agent_record.message == cert.get_message(peer_public_key_1))

    # error: wrong signer
    with pytest.raises(
            ValueError,
            match=
            "Invalid signature for provided representative_public_key and agent address!",
    ):
        AgentRecord.from_cert_request(cert, agent_key_2.address,
                                      peer_public_key_1)

    # error: wrong signer
    with pytest.raises(
            ValueError,
            match=
            "Invalid signature for provided representative_public_key and agent address!",
    ):
        AgentRecord.from_cert_request(cert, agent_key_1.address,
                                      peer_public_key_2)
Beispiel #3
0
def _get_cert_requests(project_directory: str, manager: AgentConfigManager,
                       connection_id: PublicId) -> List[CertRequest]:
    """
    Get certificate requests, taking the overrides into account.

    :param project_directory: aea project directory.
    :param manager: AgentConfigManager
    :param connection_id: the connection id.

    :return: the list of cert requests.
    """
    path = get_dotted_package_path_unified(project_directory,
                                           manager.agent_config, CONNECTION,
                                           connection_id)
    path_to_cert_requests = f"{path}.cert_requests"

    try:
        cert_requests = manager.get_variable(path_to_cert_requests)
    except VariableDoesNotExist:
        return []

    cert_requests = cast(List[Dict], cert_requests)
    return [
        CertRequest.from_json(cert_request_json)
        for cert_request_json in cert_requests
    ]
Beispiel #4
0
    def setup_class(cls):
        """Set the test up"""
        cls.cwd = os.getcwd()
        cls.t = tempfile.mkdtemp()
        os.chdir(cls.t)
        crypto = make_crypto(DEFAULT_LEDGER)
        cls.node_host = "localhost"
        cls.node_port = "11234"
        cls.identity = Identity("", address=crypto.address)

        cls.key_file = os.path.join(cls.t, "keyfile")
        key_file_desc = open(cls.key_file, "ab")
        crypto.dump(key_file_desc)
        key_file_desc.close()

        cls.peer_crypto = make_crypto(DEFAULT_LEDGER)
        cls.cert_request = CertRequest(
            cls.peer_crypto.public_key,
            POR_DEFAULT_SERVICE_ID,
            DEFAULT_LEDGER,
            "2021-01-01",
            "2021-01-02",
            f"./{crypto.address}_cert.txt",
        )
        _process_cert(crypto, cls.cert_request, cls.t)
Beispiel #5
0
def _process_certificate(
    path_prefix: str,
    agent_config: AgentConfig,
    cert_request: CertRequest,
    connection_id: PublicId,
) -> None:
    """Process a single certificate request."""
    ledger_id = cert_request.ledger_id
    if cert_request.key_identifier is not None:
        key_identifier = cert_request.key_identifier
        connection_private_key_path = agent_config.connection_private_key_paths.read(
            key_identifier)
        if connection_private_key_path is None:
            raise ClickException(
                f"Cannot find connection private key with id '{key_identifier}'. Connection '{connection_id}' requires this. Please use `aea generate-key {key_identifier} connection_{key_identifier}_private_key.txt` and `aea add-key {key_identifier} connection_{key_identifier}_private_key.txt --connection` to add a connection private key with id '{key_identifier}'."
            )
        new_connection_private_key_path = prepend_if_not_absolute(
            connection_private_key_path, path_prefix)
        connection_crypto = crypto_registry.make(
            key_identifier, private_key_path=new_connection_private_key_path)
        public_key = connection_crypto.public_key
    else:
        public_key = cast(str, cert_request.public_key)
        enforce(
            public_key is not None,
            "Internal error - one of key_identifier or public_key must be not None.",
        )
    crypto_private_key_path = agent_config.private_key_paths.read(ledger_id)
    if crypto_private_key_path is None:
        raise ClickException(
            f"Cannot find private key with id '{ledger_id}'. Please use `aea generate-key {key_identifier}` and `aea add-key {key_identifier}` to add a private key with id '{key_identifier}'."
        )
    message = cert_request.get_message(public_key)
    output_path = cert_request.get_absolute_save_path(path_prefix)
    absolute_crypto_private_key_path = prepend_if_not_absolute(
        crypto_private_key_path, path_prefix)
    cert = make_certificate(
        ledger_id,
        str(absolute_crypto_private_key_path),
        message,
        str(output_path),
    )
    click.echo(f"Generated signature: '{cert}'")
    click.echo(
        f"Dumped certificate '{cert_request.identifier}' in '{output_path}' for connection {connection_id}."
    )
Beispiel #6
0
 def from_cert_request(
     cls,
     cert_request: CertRequest,
     address: str,
     representative_public_key: str,
 ) -> "AgentRecord":
     """Get agent record from cert request."""
     message = cert_request.get_message(representative_public_key)
     signature = cert_request.get_signature()
     record = cls(
         address,
         representative_public_key,
         message,
         signature,
         cert_request.ledger_id,
     )
     return record
Beispiel #7
0
    def setup_class(cls):
        """Set up the class."""
        super().setup_class()

        cls.cert_id_3 = "cert_id_3"
        cls.cert_id_4 = "cert_id_4"
        cls.expected_path_3 = os.path.abspath("path_3")
        cls.expected_path_4 = os.path.abspath("path_4")
        cls.cert_request_3 = CertRequest(
            identifier=cls.cert_id_3,
            ledger_id=ETHEREUM,
            not_after="2020-01-02",
            not_before="2020-01-01",
            public_key=ETHEREUM,
            save_path=cls.expected_path_3,
        )
        cls.cert_request_4 = CertRequest(
            identifier=cls.cert_id_4,
            ledger_id=ETHEREUM,
            not_after="2020-01-02",
            not_before="2020-01-01",
            public_key="0xABCDEF123456",
            save_path=cls.expected_path_4,
        )

        # Add override configurations
        dotted_path = f"connections.{DummyConnection.connection_id.name}.cert_requests"
        json_3 = json.dumps(cls.cert_request_3.json).replace("'", '"')
        json_4 = json.dumps(cls.cert_request_4.json).replace("'", '"')
        new_cert_requests = f"[{json_3}, {json_4}]"
        cls.set_config(dotted_path, new_cert_requests, type_="list")

        # add ethereum key and connection key
        shutil.copy(
            ETHEREUM_PRIVATE_KEY_PATH,
            os.path.join(cls.current_agent_context, ETHEREUM_PRIVATE_KEY_FILE),
        )
        cls.add_private_key(
            ledger_api_id=ETHEREUM, private_key_filepath=ETHEREUM_PRIVATE_KEY_FILE
        )
        cls.add_private_key(
            ledger_api_id=ETHEREUM,
            private_key_filepath=ETHEREUM_PRIVATE_KEY_FILE,
            connection=True,
        )
Beispiel #8
0
 def test_error(self):
     """Test error during instantiation.."""
     with pytest.raises(ValueError, match=self.ERROR_MESSAGE_PATTERN):
         CertRequest(
             self.PUBLIC_KEY,
             self.IDENTIFIER,
             self.LEDGER_ID,
             self.NOT_BEFORE,
             self.NOT_AFTER,
             self.PATH,
         )
Beispiel #9
0
 def setup_class(cls):
     """Set up class."""
     super().setup_class()
     cls.cert_id_1 = "cert_id_1"
     cls.cert_request_1 = CertRequest(
         identifier=cls.cert_id_1,
         ledger_id=FETCHAI,
         not_after="2020-01-02",
         not_before="2020-01-01",
         public_key="bad_ledger_id",
         save_path="path",
     )
     cls.add_cert_requests([cls.cert_request_1], DummyConnection.connection_id.name)
Beispiel #10
0
 def setup_class(cls):
     """Set up class."""
     cls.expected_public_key = cls.PUBLIC_KEY
     cls.expected_identifier = "identifier"
     cls.expected_ledger_id = "ledger_id"
     cls.not_before = "2020-01-01"
     cls.not_after = "2020-01-02"
     cls.expected_path = os.path.abspath("some/path")
     cls.cert_request = CertRequest(
         cls.expected_public_key,
         cls.expected_identifier,
         cls.expected_ledger_id,
         cls.not_before,
         cls.not_after,
         cls.expected_path,
     )
Beispiel #11
0
    def test_connection(self):
        """Test the connection can be used in an aea."""
        self.generate_private_key()
        self.add_private_key()
        self.add_item("connection", str(PUBLIC_ID))
        conn_path = "vendor.fetchai.connections.p2p_libp2p_client"
        self.nested_set_config(
            conn_path + ".config",
            {
                "nodes":
                [{
                    "uri": "{}:{}".format(DEFAULT_HOST, DEFAULT_DELEGATE_PORT),
                    "public_key": self.node_connection.node.pub,
                }]
            },
        )

        # generate certificates for connection
        self.nested_set_config(
            conn_path + ".cert_requests",
            [
                CertRequest(
                    identifier="acn",
                    ledger_id="fetchai",
                    not_after="2022-01-01",
                    not_before="2021-01-01",
                    public_key=self.node_connection.node.pub,
                    save_path="./cli_test_cert.txt",
                )
            ],
        )
        self.run_cli_command("issue-certificates", cwd=self._get_cwd())

        process = self.run_agent()
        is_running = self.is_running(process, timeout=DEFAULT_LAUNCH_TIMEOUT)
        assert is_running, "AEA not running within timeout!"

        check_strings = "Successfully connected to libp2p node {}:{}".format(
            DEFAULT_HOST, DEFAULT_DELEGATE_PORT)
        missing_strings = self.missing_from_output(process, check_strings)
        assert (
            missing_strings == []
        ), "Strings {} didn't appear in agent output.".format(missing_strings)

        self.terminate_agents(process)
        assert self.is_successfully_terminated(
            process), "AEA wasn't successfully terminated."
Beispiel #12
0
    def test_connectivity(self):
        """Test connectivity."""
        self.generate_private_key()
        self.add_private_key()
        self.add_item("connection", str(P2P_CLIENT_CONNECTION_PUBLIC_ID))
        config_path = "vendor.fetchai.connections.p2p_libp2p_client.config"
        self.nested_set_config(
            config_path,
            {"nodes": [{"uri": "{}".format(uri)} for uri in PUBLIC_DHT_DELEGATE_URIS]},
        )
        conn_path = "vendor.fetchai.connections.p2p_libp2p_client"
        self.nested_set_config(
            conn_path + ".config",
            {
                "nodes": [
                    {"uri": uri, "public_key": PUBLIC_DHT_PUBLIC_KEYS[i]}
                    for i, uri in enumerate(PUBLIC_DHT_DELEGATE_URIS)
                ]
            },
        )

        # generate certificates for connection
        self.nested_set_config(
            conn_path + ".cert_requests",
            [
                CertRequest(
                    identifier="acn",
                    ledger_id="fetchai",
                    not_after="2022-01-01",
                    not_before="2021-01-01",
                    public_key=public_key,
                    save_path=f"./cli_test_cert_{public_key}.txt",
                )
                for public_key in PUBLIC_DHT_PUBLIC_KEYS
            ],
        )
        self.run_cli_command("issue-certificates", cwd=self._get_cwd())

        process = self.run_agent()
        is_running = self.is_running(process, timeout=AEA_DEFAULT_LAUNCH_TIMEOUT)
        assert is_running, "AEA not running within timeout!"

        self.terminate_agents(process)
        assert self.is_successfully_terminated(
            process
        ), "AEA wasn't successfully terminated."
Beispiel #13
0
 def setup_class(cls):
     """Set up class."""
     super().setup_class()
     cls.cert_id_1 = "cert_id_1"
     cls.cert_request_1 = CertRequest(
         identifier=cls.cert_id_1,
         ledger_id="bad_ledger_id",
         not_after="2020-01-02",
         not_before="2020-01-01",
         public_key=FETCHAI,
         save_path="path",
     )
     cls.add_cert_requests([cls.cert_request_1], DummyConnection.connection_id.name)
     # add fetchai key and connection key
     cls.generate_private_key()
     cls.add_private_key()
     cls.add_private_key(connection=True)
def _process_certificate(
    project_directory: str,
    agent_config: AgentConfig,
    cert_request: CertRequest,
    connection_id: PublicId,
):
    """Process a single certificate request."""
    ledger_id = cert_request.ledger_id
    output_path = cert_request.save_path
    if cert_request.key_identifier is not None:
        key_identifier = cert_request.key_identifier
        connection_private_key_path = agent_config.connection_private_key_paths.read(
            key_identifier)
        if connection_private_key_path is None:
            raise ClickException(
                f"Cannot find connection private key with id '{key_identifier}'. Connection '{connection_id}' requires this. Please use `aea generate-key {key_identifier} connection_{key_identifier}_private_key.txt` and `aea add-key {key_identifier} connection_{key_identifier}_private_key.txt --connection` to add a connection private key with id '{key_identifier}'."
            )
        connection_crypto = crypto_registry.make(
            key_identifier, private_key_path=connection_private_key_path)
        public_key = connection_crypto.public_key
    else:
        public_key = cast(str, cert_request.public_key)
        enforce(
            public_key is not None,
            "Internal error - one of key_identifier or public_key must be not None.",
        )
    crypto_private_key_path = agent_config.private_key_paths.read(ledger_id)
    if crypto_private_key_path is None:
        raise ClickException(
            f"Cannot find private key with id '{ledger_id}'. Please use `aea generate-key {key_identifier}` and `aea add-key {key_identifier}` to add a private key with id '{key_identifier}'."
        )
    message = cert_request.get_message(public_key)
    cert = make_certificate(
        ledger_id,
        crypto_private_key_path,
        message,
        os.path.join(project_directory, output_path),
    )
    click.echo(f"Generated signature: '{cert}'")
Beispiel #15
0
def run():
    """Run demo."""

    # Create a private key
    create_private_key(FetchAICrypto.identifier, FETCHAI_PRIVATE_KEY_FILE)
    create_private_key(FetchAICrypto.identifier, FETCHAI_PRIVATE_KEY_FILE_CONNECTION)

    # Set up the wallet, identity and (empty) resources
    wallet = Wallet(
        private_key_paths={FetchAICrypto.identifier: FETCHAI_PRIVATE_KEY_FILE},
        connection_private_key_paths={
            FetchAICrypto.identifier: FETCHAI_PRIVATE_KEY_FILE_CONNECTION
        },
    )
    identity = Identity(
        "my_aea", address=wallet.addresses.get(FetchAICrypto.identifier)
    )
    resources = Resources()
    data_dir = os.getcwd()

    # specify the default routing for some protocols
    default_routing = {
        LedgerApiMessage.protocol_id: LedgerConnection.connection_id,
        OefSearchMessage.protocol_id: SOEFConnection.connection_id,
    }
    default_connection = P2PLibp2pConnection.connection_id

    state_update_protocol = Protocol.from_dir(
        os.path.join(os.getcwd(), "packages", "fetchai", "protocols", "state_update")
    )
    resources.add_protocol(state_update_protocol)

    # Add the default protocol (which is part of the AEA distribution)
    default_protocol = Protocol.from_dir(
        os.path.join(os.getcwd(), "packages", "fetchai", "protocols", "default")
    )
    resources.add_protocol(default_protocol)

    # Add the signing protocol (which is part of the AEA distribution)
    signing_protocol = Protocol.from_dir(
        os.path.join(os.getcwd(), "packages", "fetchai", "protocols", "signing")
    )
    resources.add_protocol(signing_protocol)

    # Add the ledger_api protocol
    ledger_api_protocol = Protocol.from_dir(
        os.path.join(os.getcwd(), "packages", "fetchai", "protocols", "ledger_api",)
    )
    resources.add_protocol(ledger_api_protocol)

    # Add the oef_search protocol
    oef_protocol = Protocol.from_dir(
        os.path.join(os.getcwd(), "packages", "fetchai", "protocols", "oef_search",)
    )
    resources.add_protocol(oef_protocol)

    # Add the fipa protocol
    fipa_protocol = Protocol.from_dir(
        os.path.join(os.getcwd(), "packages", "fetchai", "protocols", "fipa",)
    )
    resources.add_protocol(fipa_protocol)

    # Add the LedgerAPI connection
    configuration = ConnectionConfig(connection_id=LedgerConnection.connection_id)
    ledger_api_connection = LedgerConnection(
        configuration=configuration, data_dir=data_dir, identity=identity
    )
    resources.add_connection(ledger_api_connection)

    # Add the P2P connection
    cert_path = ".certs/conn_cert.txt"
    cert_request = CertRequest(
        identifier="acn",
        ledger_id=FetchAICrypto.identifier,
        not_after="2022-01-01",
        not_before="2021-01-01",
        public_key="fetchai",
        save_path=cert_path,
    )
    public_key = wallet.connection_cryptos.public_keys.get(FetchAICrypto.identifier)
    message = cert_request.get_message(public_key)
    make_certificate(
        FetchAICrypto.identifier, FETCHAI_PRIVATE_KEY_FILE, message, cert_path
    )
    configuration = ConnectionConfig(
        connection_id=P2PLibp2pConnection.connection_id,
        delegate_uri="127.0.0.1:11001",
        entry_peers=[ENTRY_PEER_ADDRESS],
        local_uri="127.0.0.1:9001",
        log_file="libp2p_node.log",
        public_uri="127.0.0.1:9001",
        build_directory=os.getcwd(),
        build_entrypoint="check_dependencies.py",
        cert_requests=[cert_request],
    )
    configuration.directory = os.path.dirname(
        packages.fetchai.connections.p2p_libp2p.connection.__file__
    )

    AEABuilder.run_build_for_component_configuration(configuration)

    p2p_connection = P2PLibp2pConnection(
        configuration=configuration,
        data_dir=data_dir,
        identity=identity,
        crypto_store=wallet.connection_cryptos,
    )
    resources.add_connection(p2p_connection)

    # Add the SOEF connection
    configuration = ConnectionConfig(
        api_key=API_KEY,
        soef_addr=SOEF_ADDR,
        soef_port=SOEF_PORT,
        restricted_to_protocols={OefSearchMessage.protocol_id},
        connection_id=SOEFConnection.connection_id,
    )
    soef_connection = SOEFConnection(
        configuration=configuration, data_dir=data_dir, identity=identity
    )
    resources.add_connection(soef_connection)

    # create the AEA
    my_aea = AEA(
        identity,
        wallet,
        resources,
        data_dir,
        default_connection=default_connection,
        default_routing=default_routing,
    )
    # Add the error and weather_client skills
    error_skill = Skill.from_dir(
        os.path.join(ROOT_DIR, "packages", "fetchai", "skills", "error"),
        agent_context=my_aea.context,
    )
    weather_skill = Skill.from_dir(
        os.path.join(ROOT_DIR, "packages", "fetchai", "skills", "weather_client"),
        agent_context=my_aea.context,
    )

    strategy = cast(Strategy, weather_skill.models.get("strategy"))
    strategy._is_ledger_tx = False

    for skill in [error_skill, weather_skill]:
        resources.add_skill(skill)

    # Run the AEA
    try:
        logger.info("STARTING AEA NOW!")
        my_aea.start()
    except KeyboardInterrupt:
        logger.info("STOPPING AEA NOW!")
        my_aea.stop()