def setup_class(cls):
     """Set up the test class."""
     cls.crypto1 = Crypto()
     cls.crypto2 = Crypto()
     cls.mailbox1 = OEFMailBox(cls.crypto1.public_key,
                               oef_addr="127.0.0.1",
                               oef_port=10000)
     cls.mailbox2 = OEFMailBox(cls.crypto2.public_key,
                               oef_addr="127.0.0.1",
                               oef_port=10000)
     cls.mailbox1.connect()
     cls.mailbox2.connect()
示例#2
0
    def setup_class(cls):
        """Test that if the controller agent does not receive enough registrations, it stops."""
        tac_parameters = TACParameters(min_nb_agents=2,
                                       start_time=datetime.datetime.now(),
                                       registration_timeout=5)
        cls.controller_agent = ControllerAgent('controller', '127.0.0.1',
                                               10000, tac_parameters,
                                               NullMonitor())

        cls.controller_agent.mailbox.connect()
        job = Thread(target=cls.controller_agent.start)
        job.start()

        cls.crypto = Crypto()
        cls.agent1 = TOEFAgent(cls.crypto.public_key,
                               oef_addr='127.0.0.1',
                               oef_port=10000)
        cls.agent1.connect()

        tac_msg = TACMessage(tac_type=TACMessage.Type.REGISTER,
                             agent_name='agent_name')
        tac_bytes = TACSerializer().encode(tac_msg)
        cls.agent1.outbox.put_message(
            to=cls.controller_agent.crypto.public_key,
            sender=cls.crypto.public_key,
            protocol_id=TACMessage.protocol_id,
            message=tac_bytes)

        job.join()
示例#3
0
def test_react():
    """Tests income messages."""
    node = LocalNode()
    agent_name = "MyAgent"
    private_key_pem_path = os.path.join(CUR_PATH, "data", "priv.pem")
    crypto = Crypto(private_key_pem_path=private_key_pem_path)
    public_key = crypto.public_key
    mailbox = MailBox(OEFLocalConnection(public_key, node))

    msg = DefaultMessage(type=DefaultMessage.Type.BYTES, content=b"hello")
    message_bytes = DefaultSerializer().encode(msg)

    envelope = Envelope(to="Agent1",
                        sender=public_key,
                        protocol_id="default",
                        message=message_bytes)

    agent = AEA(agent_name,
                mailbox,
                private_key_pem_path=private_key_pem_path,
                directory=str(Path(CUR_PATH, "data", "dummy_aea")))
    t = Thread(target=agent.start)
    try:
        t.start()
        agent.mailbox.inbox._queue.put(envelope)
        time.sleep(1)
        handler = agent.resources \
            .handler_registry.fetch_by_skill('default', "dummy")
        assert envelope in handler.handled_envelopes, \
            "The envelope is not inside the handled_envelopes."
    finally:
        agent.stop()
        t.join()
def test_connection(network_node):
    """Test that a mailbox can connect to the OEF."""
    crypto = Crypto()
    mailbox = OEFMailBox(crypto.public_key,
                         oef_addr="127.0.0.1",
                         oef_port=10000)
    mailbox.connect()

    mailbox.disconnect()
示例#5
0
def _create_temporary_private_key() -> bytes:
    """
    Create a temporary private key.

    :return: the private key in pem format.
    """
    crypto = Crypto()
    pem = crypto._private_key.private_bytes(Encoding.PEM,
                                            PrivateFormat.TraditionalOpenSSL,
                                            NoEncryption())  # type: ignore
    return pem
示例#6
0
def test_initialization_from_existing_private_key():
    """Test that the initialization from an existing private key works correctly."""
    private_key_pem_path = ROOT_DIR + "/tests/data/priv.pem"

    private_key = load_pem_private_key(
        open(private_key_pem_path, "rb").read(), None, default_backend())

    c = Crypto(private_key_pem_path=private_key_pem_path)

    expected_public_key = private_key.public_key().public_bytes(
        encoding=Encoding.PEM, format=PublicFormat.SubjectPublicKeyInfo)
    actual_public_key = c.public_key_pem
    assert expected_public_key == actual_public_key
示例#7
0
def test_handle():
    """Tests handle method of an agent."""
    node = LocalNode()
    agent_name = "MyAgent"
    private_key_pem_path = os.path.join(CUR_PATH, "data", "priv.pem")
    crypto = Crypto(private_key_pem_path=private_key_pem_path)
    public_key = crypto.public_key
    mailbox = MailBox(OEFLocalConnection(public_key, node))

    msg = DefaultMessage(type=DefaultMessage.Type.BYTES, content=b"hello")
    message_bytes = DefaultSerializer().encode(msg)

    envelope = Envelope(to="Agent1",
                        sender=public_key,
                        protocol_id="unknown_protocol",
                        message=message_bytes)

    agent = AEA(agent_name,
                mailbox,
                private_key_pem_path=private_key_pem_path,
                directory=str(Path(CUR_PATH, "data", "dummy_aea")))
    t = Thread(target=agent.start)
    try:
        t.start()
        agent.mailbox.inbox._queue.put(envelope)
        env = agent.mailbox.outbox._queue.get(block=True, timeout=5.0)
        assert env.protocol_id == "default", \
            "The envelope is not the expected protocol (Unsupported protocol)"

        #   DECODING ERROR
        msg = "hello".encode("utf-8")
        envelope = Envelope(to=public_key,
                            sender=public_key,
                            protocol_id='default',
                            message=msg)
        agent.mailbox.inbox._queue.put(envelope)
        #   UNSUPPORTED SKILL
        msg = FIPASerializer().encode(
            FIPAMessage(performative=FIPAMessage.Performative.ACCEPT,
                        message_id=0,
                        dialogue_id=0,
                        destination=public_key,
                        target=1))
        envelope = Envelope(to=public_key,
                            sender=public_key,
                            protocol_id="fipa",
                            message=msg)
        agent.mailbox.inbox._queue.put(envelope)
    finally:
        agent.stop()
        t.join()
示例#8
0
    def transfer(
        self,
        crypto: Crypto,
        destination_address: Address,
        amount: int,
        tx_fee: int,
        tx_nonce: str,
        chain_id: int = 1,
        **kwargs,
    ) -> Optional[str]:
        """
        Submit a transfer transaction to the ledger.

        :param crypto: the crypto object associated to the payer.
        :param destination_address: the destination address of the payee.
        :param amount: the amount of wealth to be transferred.
        :param tx_fee: the transaction fee.
        :param tx_nonce: verifies the authenticity of the tx
        :param chain_id: the Chain ID of the Ethereum transaction. Default is 1 (i.e. mainnet).
        :return: tx digest if present, otherwise None
        """
        tx_digest = None
        nonce = self._try_get_transaction_count(crypto.address)
        if nonce is None:
            return tx_digest

        transaction = {
            "nonce": nonce,
            "chainId": chain_id,
            "to": destination_address,
            "value": amount,
            "gas": tx_fee,
            "gasPrice": self._api.toWei(self._gas_price, GAS_ID),
            "data": tx_nonce,
        }

        gas_estimate = self._try_get_gas_estimate(transaction)
        if gas_estimate is None or tx_fee <= gas_estimate:  # pragma: no cover
            logger.warning(
                "Need to increase tx_fee in the configs to cover the gas consumption of the transaction. Estimated gas consumption is: {}.".format(
                    gas_estimate
                )
            )
            return tx_digest

        signed_transaction = crypto.sign_transaction(transaction)

        tx_digest = self.send_signed_transaction(tx_signed=signed_transaction,)

        return tx_digest
示例#9
0
def _try_validate_private_key_pem_path(private_key_pem_path: str) -> None:
    """
    Try to validate a private key.

    :param private_key_pem_path: the path to the private key.
    :return: None
    :raises: an exception if the private key is invalid.
    """
    try:
        Crypto(private_key_pem_path=private_key_pem_path)
    except ValueError:
        logger.error("This is not a valid private key file: '{}'".format(
            private_key_pem_path))
        exit(-1)
示例#10
0
        def setup_class(cls):
            """
            Set the test up.

            Steps:
            - Register a service
            - Check that the registration worked.
            """
            cls.crypto1 = Crypto()
            cls.mailbox1 = OEFMailBox(cls.crypto1.public_key,
                                      oef_addr="127.0.0.1",
                                      oef_port=10000)
            cls.mailbox1.connect()

            cls.request_id = 1
            cls.foo_datamodel = DataModel(
                "foo", [Attribute("bar", int, True, "A bar attribute.")])
            cls.desc = Description({"bar": 1}, data_model=cls.foo_datamodel)
            msg = OEFMessage(oef_type=OEFMessage.Type.REGISTER_SERVICE,
                             id=cls.request_id,
                             service_description=cls.desc,
                             service_id="")
            msg_bytes = OEFSerializer().encode(msg)
            cls.mailbox1.outbox.put_message(to=DEFAULT_OEF,
                                            sender=cls.crypto1.public_key,
                                            protocol_id=OEFMessage.protocol_id,
                                            message=msg_bytes)

            time.sleep(1.0)

            cls.request_id += 1
            search_request = OEFMessage(
                oef_type=OEFMessage.Type.SEARCH_SERVICES,
                id=cls.request_id,
                query=Query([Constraint("bar", ConstraintType("==", 1))],
                            model=cls.foo_datamodel))
            cls.mailbox1.outbox.put_message(
                to=DEFAULT_OEF,
                sender=cls.crypto1.public_key,
                protocol_id=OEFMessage.protocol_id,
                message=OEFSerializer().encode(search_request))
            envelope = cls.mailbox1.inbox.get(block=True, timeout=5.0)
            search_result = OEFSerializer().decode(envelope.message)
            assert search_result.get("type") == OEFMessage.Type.SEARCH_RESULT
            assert search_result.get("id") == cls.request_id
            assert search_result.get("agents") == [cls.crypto1.public_key]
示例#11
0
def run(ctx: Context, connection_name: str):
    """Run the agent."""
    _try_to_load_agent_config(ctx)
    agent_name = cast(str, ctx.agent_config.agent_name)
    private_key_pem_path = cast(str, ctx.agent_config.private_key_pem_path)
    if private_key_pem_path == "":
        private_key_pem_path = _create_temporary_private_key_pem_path()
    else:
        _try_validate_private_key_pem_path(private_key_pem_path)
    crypto = Crypto(private_key_pem_path=private_key_pem_path)
    public_key = crypto.public_key
    connection_name = ctx.agent_config.default_connection if connection_name is None else connection_name
    _try_to_load_protocols(ctx)
    try:
        connection = _setup_connection(connection_name, public_key, ctx)
    except AEAConfigException as e:
        logger.error(str(e))
        exit(-1)
        return

    logger.debug("Installing all the dependencies...")
    for d in ctx.get_dependencies():
        logger.debug("Installing {}...".format(d))
        try:
            subp = subprocess.Popen(
                [sys.executable, "-m", "pip", "install", d])
            subp.wait(30.0)
        except Exception:
            logger.error(
                "An error occurred while installing {}. Stopping...".format(d))
            exit(-1)

    mailbox = MailBox(connection)
    agent = AEA(agent_name,
                mailbox,
                private_key_pem_path=private_key_pem_path,
                directory=str(Path(".")))
    try:
        agent.start()
    except KeyboardInterrupt:
        logger.info("Interrupted.")
    except Exception as e:
        logger.exception(e)
    finally:
        agent.stop()
示例#12
0
def test_act():
    """Tests the act function of the AeA."""
    node = LocalNode()
    agent_name = "MyAgent"
    private_key_pem_path = os.path.join(CUR_PATH, "data", "priv.pem")
    crypto = Crypto(private_key_pem_path=private_key_pem_path)
    public_key = crypto.public_key
    mailbox = MailBox(OEFLocalConnection(public_key, node))

    agent = AEA(agent_name,
                mailbox,
                private_key_pem_path=private_key_pem_path,
                directory=str(Path(CUR_PATH, "data", "dummy_aea")))
    t = Thread(target=agent.start)
    try:
        t.start()
        time.sleep(1)

        behaviour = agent.resources.behaviour_registry.fetch("dummy")
        assert behaviour[0].nb_act_called > 0, "Act() wasn't called"
    finally:
        agent.stop()
        t.join()
示例#13
0
    def __init__(self,
                 name: str,
                 private_key_pem_path: Optional[str] = None,
                 timeout: float = 1.0,
                 debug: bool = False) -> None:
        """
        Instantiate the agent.

        :param name: the name of the agent
        :param private_key_pem_path: the path to the private key of the agent.
        :param timeout: the time in (fractions of) seconds to time out an agent between act and react
        :param debug: if True, run the agent in debug mode.

        :return: None
        """
        self._name = name
        self._crypto = Crypto(private_key_pem_path=private_key_pem_path)
        self._liveness = Liveness()
        self._timeout = timeout

        self.debug = debug

        self.mailbox = None  # type: Optional[MailBox]
示例#14
0
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.
#
# ------------------------------------------------------------------------------

"""
Generate a private key to be used for the Trading Agent Competition.

It prints the key in PEM format to the specified file.
"""

from cryptography.hazmat.primitives.serialization import Encoding, PrivateFormat, NoEncryption

import argparse

from aea.crypto.base import Crypto

parser = argparse.ArgumentParser("generate_private_key", description=__doc__)
parser.add_argument("out_file", type=str, help="Where to save the private key.")

if __name__ == '__main__':
    args = parser.parse_args()

    crypto = Crypto()
    pem = crypto._private_key.private_bytes(Encoding.PEM, PrivateFormat.TraditionalOpenSSL, NoEncryption())  # type: ignore
    file = open(args.out_file, "wb")
    file.write(pem)
    file.close()
示例#15
0
    def transfer(
        self,
        crypto: Crypto,
        destination_address: Address,
        amount: int,
        tx_fee: int,
        tx_nonce: str = "",
        denom: str = "testfet",
        account_number: int = 0,
        sequence: int = 0,
        gas: int = 80000,
        memo: str = "",
        sync_mode: str = "sync",
        chain_id: str = "aea-testnet",
        **kwargs,
    ) -> Optional[str]:
        """
        Submit a transfer transaction to the ledger.

        :param crypto: the crypto object associated to the payer.
        :param destination_address: the destination address of the payee.
        :param amount: the amount of wealth to be transferred.
        :param tx_fee: the transaction fee.
        :param tx_nonce: verifies the authenticity of the tx
        :param chain_id: the Chain ID of the Ethereum transaction. Default is 1 (i.e. mainnet).
        :return: tx digest if present, otherwise None
        """
        result = self._try_get_account_number_and_sequence(crypto.address)
        if result is not None:
            account_number, sequence = result
        transfer = {
            "type": "cosmos-sdk/MsgSend",
            "value": {
                "from_address": crypto.address,
                "to_address": destination_address,
                "amount": [{
                    "denom": denom,
                    "amount": str(amount)
                }],
            },
        }
        tx = {
            "account_number": str(account_number),
            "sequence": str(sequence),
            "chain_id": chain_id,
            "fee": {
                "gas": str(gas),
                "amount": [{
                    "denom": denom,
                    "amount": str(tx_fee)
                }],
            },
            "memo": memo,
            "msgs": [transfer],
        }
        signature = crypto.sign_transaction(tx)
        base64_pbk = base64.b64encode(bytes.fromhex(
            crypto.public_key)).decode("utf-8")
        pushable_tx = {
            "tx": {
                "msg": [transfer],
                "fee": {
                    "gas": str(gas),
                    "amount": [{
                        "denom": denom,
                        "amount": str(tx_fee)
                    }],
                },
                "memo":
                memo,
                "signatures": [{
                    "signature": signature,
                    "pub_key": {
                        "type": "tendermint/PubKeySecp256k1",
                        "value": base64_pbk,
                    },
                    "account_number": str(account_number),
                    "sequence": str(sequence),
                }],
            },
            "mode": sync_mode,
        }
        # TODO retrieve, gas dynamically
        tx_digest = self.send_signed_transaction(tx_signed=pushable_tx)
        return tx_digest
示例#16
0
def test_example(network_node):
    """Test the mailbox."""
    crypto1 = Crypto()
    crypto2 = Crypto()

    mailbox1 = OEFMailBox(crypto1.public_key, "127.0.0.1", 10000)
    mailbox2 = OEFMailBox(crypto2.public_key, "127.0.0.1", 10000)

    mailbox1.connect()
    mailbox2.connect()

    msg = DefaultMessage(type=DefaultMessage.Type.BYTES, content=b"hello")
    msg_bytes = DefaultSerializer().encode(msg)
    mailbox1.outbox.put(
        Envelope(
            to=crypto2.public_key,
            sender=crypto1.public_key,
            protocol_id=DefaultMessage.protocol_id,
            message=msg_bytes,
        ))

    msg = FIPAMessage(
        message_id=0,
        dialogue_id=0,
        target=0,
        performative=FIPAMessage.Performative.CFP,
        query=None,
    )
    msg_bytes = FIPASerializer().encode(msg)
    mailbox1.outbox.put(
        Envelope(
            to=crypto2.public_key,
            sender=crypto1.public_key,
            protocol_id=FIPAMessage.protocol_id,
            message=msg_bytes,
        ))

    msg = FIPAMessage(
        message_id=0,
        dialogue_id=0,
        target=0,
        performative=FIPAMessage.Performative.PROPOSE,
        proposal=[],
    )
    msg_bytes = FIPASerializer().encode(msg)
    mailbox1.outbox.put(
        Envelope(
            to=crypto2.public_key,
            sender=crypto1.public_key,
            protocol_id=FIPAMessage.protocol_id,
            message=msg_bytes,
        ))

    msg = FIPAMessage(
        message_id=0,
        dialogue_id=0,
        target=0,
        performative=FIPAMessage.Performative.ACCEPT,
    )
    msg_bytes = FIPASerializer().encode(msg)
    mailbox1.outbox.put(
        Envelope(
            to=crypto2.public_key,
            sender=crypto1.public_key,
            protocol_id=FIPAMessage.protocol_id,
            message=msg_bytes,
        ))

    msg = FIPAMessage(
        message_id=0,
        dialogue_id=0,
        target=0,
        performative=FIPAMessage.Performative.DECLINE,
    )
    msg_bytes = FIPASerializer().encode(msg)
    mailbox1.outbox.put(
        Envelope(
            to=crypto2.public_key,
            sender=crypto1.public_key,
            protocol_id=FIPAMessage.protocol_id,
            message=msg_bytes,
        ))

    time.sleep(5.0)

    envelope = mailbox2.inbox.get(block=True, timeout=2.0)
    msg = DefaultSerializer().decode(envelope.message)
    assert msg.get("content") == b"hello"
    envelope = mailbox2.inbox.get(block=True, timeout=2.0)
    msg = FIPASerializer().decode(envelope.message)
    assert envelope.protocol_id == "fipa"
    assert msg.get("performative") == FIPAMessage.Performative.CFP
    envelope = mailbox2.inbox.get(block=True, timeout=2.0)
    msg = FIPASerializer().decode(envelope.message)
    assert envelope.protocol_id == "fipa"
    assert msg.get("performative") == FIPAMessage.Performative.PROPOSE
    envelope = mailbox2.inbox.get(block=True, timeout=2.0)
    msg = FIPASerializer().decode(envelope.message)
    assert envelope.protocol_id == "fipa"
    assert msg.get("performative") == FIPAMessage.Performative.ACCEPT
    envelope = mailbox2.inbox.get(block=True, timeout=2.0)
    msg = FIPASerializer().decode(envelope.message)
    assert envelope.protocol_id == "fipa"
    assert msg.get("performative") == FIPAMessage.Performative.DECLINE

    mailbox1.disconnect()
    mailbox2.disconnect()