def test_get_address_from_public_key(): """Test the address from public key.""" fet_crypto = FetchAICrypto() address = FetchAICrypto().get_address_from_public_key( fet_crypto.public_key) assert str(address) == str( fet_crypto.address), "The address must be the same."
def setup(self): """Set up.""" self.crypto = FetchAICrypto() identity = Identity("", address=self.crypto.address) # create the connection and multiplexer objects configuration = ConnectionConfig( api_key="TwiCIriSl0mLahw17pyqoA", soef_addr="soef.fetch.ai", soef_port=9002, restricted_to_protocols={ PublicId.from_str("fetchai/oef_search:0.3.0") }, connection_id=SOEFConnection.connection_id, ) self.connection = SOEFConnection( configuration=configuration, identity=identity, ) self.connection.channel.unique_page_address = "some addr" self.connection2 = SOEFConnection( configuration=configuration, identity=Identity("", address=FetchAICrypto().address), ) self.loop = asyncio.get_event_loop() self.loop.run_until_complete(self.connection.connect()) self.loop.run_until_complete(self.connection2.connect())
def _make_libp2p_connection( port: Optional[int] = DEFAULT_PORT, host: Optional[str] = DEFAULT_HOST, relay: Optional[bool] = True, entry_peers: Optional[Sequence[MultiAddr]] = None, ) -> P2PLibp2pConnection: log_file = "libp2p_node_{}.log".format(port) if os.path.exists(log_file): os.remove(log_file) if relay: return P2PLibp2pConnection( FetchAICrypto().address, FetchAICrypto(), Uri("{}:{}".format(host, port)), Uri("{}:{}".format(host, port)), entry_peers=entry_peers, log_file=log_file, ) else: return P2PLibp2pConnection( FetchAICrypto().address, FetchAICrypto(), Uri("{}:{}".format(host, port)), entry_peers=entry_peers, log_file=log_file, )
def test_format_default(): """Test if default CosmosSDK transaction is correctly formated.""" account = FetchAICrypto() cc2 = FetchAICrypto() cosmos_api = FetchAIApi(**FETCHAI_TESTNET_CONFIG) amount = 10000 transfer_transaction = cosmos_api.get_transfer_transaction( sender_address=account.address, destination_address=cc2.address, amount=amount, tx_fee=1000, tx_nonce="something", ) signed_transaction = cc2.sign_transaction(transfer_transaction) assert "tx" in signed_transaction assert "signatures" in signed_transaction["tx"] assert len(signed_transaction["tx"]["signatures"]) == 1 assert "pub_key" in signed_transaction["tx"]["signatures"][0] assert "value" in signed_transaction["tx"]["signatures"][0]["pub_key"] base64_pbk = signed_transaction["tx"]["signatures"][0]["pub_key"]["value"] assert "signature" in signed_transaction["tx"]["signatures"][0] signature = signed_transaction["tx"]["signatures"][0]["signature"] default_formated_transaction = cc2.format_default_transaction( transfer_transaction, signature, base64_pbk) # Compare default formatted transaction with signed transaction assert signed_transaction == default_formated_transaction
def test_get_balance(): """Test the balance is zero for a new account.""" fetch_api = FetchAIApi(**FETCHAI_TESTNET_CONFIG) fc = FetchAICrypto() balance = fetch_api.get_balance(fc.address) assert balance == 0, "New account has a positive balance." fc = FetchAICrypto(private_key_path=FETCHAI_PRIVATE_KEY_PATH) balance = fetch_api.get_balance(fc.address)
def test_initialisation(): """Test the initialisation of the the fet crypto.""" fet_crypto = FetchAICrypto() assert fet_crypto.public_key is not None, "Public key must not be None after Initialisation" assert fet_crypto.address is not None, "Address must not be None after Initialisation" assert FetchAICrypto( PRIVATE_KEY_PATH), "Couldn't load the fet private_key from the path!" assert FetchAICrypto( "./"), "Couldn't create a new entity for the given path!"
def test_initialisation(): """Test the initialisation of the the fet crypto.""" fet_crypto = FetchAICrypto() assert (fet_crypto.public_key is not None), "Public key must not be None after Initialisation" assert (fet_crypto.address is not None), "Address must not be None after Initialisation" assert FetchAICrypto(FETCHAI_PRIVATE_KEY_PATH ), "Couldn't load the fet private_key from the path!"
def test_sign_and_recover_message(): """Test the signing and the recovery of a message.""" account = FetchAICrypto(FETCHAI_PRIVATE_KEY_PATH) sign_bytes = account.sign_message(message=b"hello") assert len(sign_bytes) > 0, "The len(signature) must not be 0" recovered_addresses = FetchAIApi.recover_message(message=b"hello", signature=sign_bytes) assert (account.address in recovered_addresses), "Failed to recover the correct address."
def test_format_cosmwasm(): """Test if CosmWasm transaction is correctly formated.""" cc2 = FetchAICrypto() # Dummy CosmWasm transaction wasm_transaction = { "account_number": "8", "chain_id": "agent-land", "fee": { "amount": [], "gas": "200000" }, "memo": "", "msgs": [{ "type": "wasm/execute", "value": { "sender": "cosmos14xjnl2mwwfz6pztpwzj6s89npxr0e3lhxl52nv", "contract": "cosmos1xzlgeyuuyqje79ma6vllregprkmgwgav5zshcm", "msg": { "create_single": { "item_owner": "cosmos1fz0dcvvqv5at6dl39804jy92lnndf3d5saalx6", "id": "1234", "path": "SOME_URI", } }, "sent_funds": [], }, }], "sequence": "25", } signed_transaction = cc2.sign_transaction(wasm_transaction) assert "value" in signed_transaction assert "signatures" in signed_transaction["value"] assert len(signed_transaction["value"]["signatures"]) == 1 assert "pub_key" in signed_transaction["value"]["signatures"][0] assert "value" in signed_transaction["value"]["signatures"][0]["pub_key"] base64_pbk = signed_transaction["value"]["signatures"][0]["pub_key"][ "value"] assert "signature" in signed_transaction["value"]["signatures"][0] signature = signed_transaction["value"]["signatures"][0]["signature"] wasm_formated_transaction = cc2.format_wasm_transaction( wasm_transaction, signature, base64_pbk) # Compare Wasm formatted transaction with signed transaction assert signed_transaction == wasm_formated_transaction
def __init__(self, **kwargs): """ Initialize a libp2p client connection. """ super().__init__(**kwargs) key_file = self.configuration.config.get( "client_key_file") # Optional[str] nodes = self.configuration.config.get("nodes") assert nodes is not None, "At least one node should be provided" nodes = list(cast(List, nodes)) nodes_uris = [node["uri"] for node in nodes] assert len(nodes_uris) == len( nodes), "Delegate Uri should be provided for each node" if (self.has_crypto_store and self.crypto_store.crypto_objects.get( "fetchai", None) is not None): # pragma: no cover key = cast(FetchAICrypto, self.crypto_store.crypto_objects["fetchai"]) elif key_file is not None: key = FetchAICrypto(key_file) else: key = FetchAICrypto() # client connection id self.key = key logger.debug("Public key used by libp2p client: {}".format( key.public_key)) # delegate uris self.delegate_uris = [Uri(node_uri) for node_uri in nodes_uris] # delegates certificates # TOFIX(LR) will be mandatory self.delegate_certs = [] # select a delegate index = random.randint(0, len(self.delegate_uris) - 1) # nosec self.node_uri = self.delegate_uris[index] # self.node_cert = self.delegate_certs[index] logger.debug("Node to use as delegate: {}".format(self.node_uri)) # tcp connection self._reader = None # type: Optional[asyncio.StreamReader] self._writer = None # type: Optional[asyncio.StreamWriter] self._loop = None # type: Optional[AbstractEventLoop] self._in_queue = None # type: Optional[asyncio.Queue] self._process_messages_task = None # type: Union[asyncio.Future, None]
def test_construct_sign_and_submit_transfer_transaction(): """Test the construction, signing and submitting of a transfer transaction.""" account = FetchAICrypto() balance = get_wealth(account.address) assert balance > 0, "Failed to fund account." fc2 = FetchAICrypto() fetchai_api = FetchAIApi(**FETCHAI_TESTNET_CONFIG) amount = 10000 assert amount < balance, "Not enough funds." transfer_transaction = fetchai_api.get_transfer_transaction( sender_address=account.address, destination_address=fc2.address, amount=amount, tx_fee=1000, tx_nonce="", ) assert isinstance( transfer_transaction, Transaction), "Incorrect transfer_transaction constructed." signed_transaction = account.sign_transaction(transfer_transaction) assert (isinstance(signed_transaction, Transaction) and len(signed_transaction.signatures) == 1), "Incorrect signed_transaction constructed." transaction_digest = fetchai_api.send_signed_transaction( signed_transaction) assert transaction_digest is not None, "Failed to submit transfer transaction!" not_settled = True elapsed_time = 0 while not_settled and elapsed_time < 20: elapsed_time += 1 time.sleep(2) transaction_receipt = fetchai_api.get_transaction_receipt( transaction_digest) if transaction_receipt is None: continue is_settled = fetchai_api.is_transaction_settled(transaction_receipt) if is_settled is None: continue not_settled = not is_settled assert transaction_receipt is not None, "Failed to retrieve transaction receipt." assert is_settled, "Failed to verify tx!" tx = fetchai_api.get_transaction(transaction_digest) assert tx != transaction_receipt, "Should be same!" is_valid = fetchai_api.is_transaction_valid(tx, fc2.address, account.address, "", amount) assert is_valid, "Failed to settle tx correctly!"
def from_config(cls, address: Address, configuration: ConnectionConfig) -> "Connection": """ Get the stub connection from the connection configuration. :param address: the address of the agent. :param configuration: the connection configuration object. :return: the connection object """ libp2p_key_file = configuration.config.get( "libp2p_key_file") # Optional[str] libp2p_host = configuration.config.get("libp2p_host") # Optional[str] libp2p_port = configuration.config.get("libp2p_port") # Optional[int] libp2p_host_public = configuration.config.get( "libp2p_public_host") # Optional[str] libp2p_port_public = configuration.config.get( "libp2p_public_port") # Optional[int] entry_peers = list( cast(List, configuration.config.get("libp2p_entry_peers"))) log_file = configuration.config.get("libp2p_log_file") # Optional[str] env_file = configuration.config.get("libp2p_env_file") # Optional[str] if libp2p_key_file is None: key = FetchAICrypto() else: key = FetchAICrypto(libp2p_key_file) uri = None if libp2p_port is not None: if libp2p_host is not None: uri = Uri(host=libp2p_host, port=libp2p_port) else: uri = Uri(host="127.0.0.1", port=libp2p_port) public_uri = None if libp2p_port_public is not None and libp2p_host_public is not None: public_uri = Uri(host=libp2p_host_public, port=libp2p_port_public) entry_peers_maddrs = [MultiAddr(maddr) for maddr in entry_peers] return P2PLibp2pConnection( address, # TOFIX(LR) need to generate signature as well key, uri, public_uri, entry_peers_maddrs, log_file, env_file, address=address, configuration=configuration, )
def setup_class(cls): """Set up the test class.""" cls.crypto1 = FetchAICrypto() cls.crypto2 = FetchAICrypto() cls.connection1 = _make_oef_connection( cls.crypto1.address, oef_addr="127.0.0.1", oef_port=10000, ) cls.connection2 = _make_oef_connection( cls.crypto2.address, oef_addr="127.0.0.1", oef_port=10000, ) cls.multiplexer1 = Multiplexer([cls.connection1]) cls.multiplexer2 = Multiplexer([cls.connection2]) cls.multiplexer1.connect() cls.multiplexer2.connect()
def setup_class(cls): """Set the test up""" cls.cwd = os.getcwd() cls.t = tempfile.mkdtemp() os.chdir(cls.t) cls.node_host = "localhost" cls.node_port = "11234" cls.identity = Identity("", address=FetchAICrypto().address) cls.key_file = os.path.join(cls.t, "keyfile") key_file_desc = open(cls.key_file, "ab") FetchAICrypto().dump(key_file_desc) key_file_desc.close()
def test_validate_transaction_fetchai(self): """Test the validate transaction for fetchai ledger.""" seller_crypto = FetchAICrypto() client_crypto = FetchAICrypto() ledger_apis = LedgerApis( { ETHEREUM: DEFAULT_ETHEREUM_CONFIG, FETCHAI: DEFAULT_FETCHAI_CONFIG }, FETCHAI, ) seller_address = str(seller_crypto.address) client_address = str(client_crypto.address) tx_contents = TxContents( digest=b"digest", action="action", chain_code="1", from_address=client_address, contract_digest="Contract_digest", contract_address=None, valid_from=1, valid_until=6, charge=10, charge_limit=2, transfers=[{ "to": seller_address, "amount": 100 }], signatories=["signatories"], data="data", ) with mock.patch.object(ledger_apis.apis.get(FETCHAI)._api.tx, "contents", return_value=tx_contents): with mock.patch.object( ledger_apis.apis.get(FETCHAI), "is_transaction_settled", return_value=True, ): result = ledger_apis.is_tx_valid( identifier=FETCHAI, tx_digest="transaction_digest", seller=seller_address, client=client_address, tx_nonce="tx_nonce", amount=100, ) assert result
def test_transfer(): """Test transfer of wealth.""" fetchai_api = FetchAIApi(**FETCHAI_TESTNET_CONFIG) fc1 = FetchAICrypto(private_key_path=FETCHAI_PRIVATE_KEY_PATH) fc2 = FetchAICrypto() amount = 40000 fee = 30000 tx_nonce = fetchai_api.generate_tx_nonce(fc2.address, fc1.address) tx_digest = fetchai_api.transfer(fc1, fc2.address, amount, fee, tx_nonce, chain_id=3) assert tx_digest is not None, "Failed to submit transfer!"
def test_generate_tx_nonce_fetchai(self): """Test the generated tx_nonce.""" seller_crypto = FetchAICrypto() client_crypto = FetchAICrypto() ledger_apis = LedgerApis( {ETHEREUM: DEFAULT_ETHEREUM_CONFIG, FETCHAI: DEFAULT_FETCHAI_CONFIG}, FETCHAI, ) seller_address = seller_crypto.address client_address = client_crypto.address tx_nonce = ledger_apis.generate_tx_nonce( FETCHAI, seller_address, client_address ) logger.info(tx_nonce) assert tx_nonce != ""
def test_get_handle_transaction_cosmwasm(): """Test the get deploy transaction method.""" cc2 = FetchAICrypto() cosmos_api = FetchAIApi(**FETCHAI_TESTNET_CONFIG) handle_msg = "handle_msg" sender_address = cc2.address contract_address = "contract_address" tx_fee = 1 amount = 10 handle_transaction = cosmos_api.get_handle_transaction( sender_address, contract_address, handle_msg, amount, tx_fee) assert type(handle_transaction) == dict and len(handle_transaction) == 6 assert "account_number" in handle_transaction assert "chain_id" in handle_transaction assert "fee" in handle_transaction and handle_transaction["fee"] == { "amount": [{ "denom": "atestfet", "amount": "{}".format(tx_fee) }], "gas": "80000", } assert "memo" in handle_transaction assert "msgs" in handle_transaction and len( handle_transaction["msgs"]) == 1 msg = handle_transaction["msgs"][0] assert "type" in msg and msg["type"] == "wasm/execute" assert ("value" in msg and msg["value"]["sender"] == sender_address and msg["value"]["contract"] == contract_address and msg["value"]["msg"] == handle_msg and msg["value"]["sent_funds"] == [{ "denom": "atestfet", "amount": str(amount) }]) assert "sequence" in handle_transaction
def test_get_deploy_transaction_cosmwasm(): """Test the get deploy transaction method.""" cc2 = FetchAICrypto() cosmos_api = FetchAIApi(**FETCHAI_TESTNET_CONFIG) contract_interface = {"wasm_byte_code": b""} deployer_address = cc2.address deploy_transaction = cosmos_api.get_deploy_transaction( contract_interface, deployer_address) assert type(deploy_transaction) == dict and len(deploy_transaction) == 6 assert "account_number" in deploy_transaction assert "chain_id" in deploy_transaction assert "fee" in deploy_transaction and deploy_transaction["fee"] == { "amount": [{ "amount": "0", "denom": "atestfet" }], "gas": "80000", } assert "memo" in deploy_transaction assert "msgs" in deploy_transaction and len( deploy_transaction["msgs"]) == 1 msg = deploy_transaction["msgs"][0] assert "type" in msg and msg["type"] == "wasm/store-code" assert ("value" in msg and msg["value"]["sender"] == deployer_address and msg["value"]["wasm_byte_code"] == contract_interface["wasm_byte_code"]) assert "sequence" in deploy_transaction
def test_get_wealth_positive(caplog): """Test the balance is zero for a new account.""" with caplog.at_level(logging.DEBUG, logger="aea.crypto.fetchai._default_logger"): fetchai_faucet_api = FetchAIFaucetApi() fc = FetchAICrypto() fetchai_faucet_api.get_wealth(fc.address)
async def test_cannot_connect_to_oef(): """Test the case when we can't connect to the OEF.""" address = FetchAICrypto().address oef_connection = OEFConnection( address=address, oef_addr="a_fake_address", oef_port=10000, connection_id=PublicId("fetchai", "oef", "0.1.0"), ) oef_connection.loop = asyncio.get_event_loop() patch = unittest.mock.patch.object( packages.fetchai.connections.oef.connection.logger, "warning" ) mocked_logger_warning = patch.__enter__() async def try_to_connect(): await oef_connection.connect() task = asyncio.ensure_future(try_to_connect(), loop=asyncio.get_event_loop()) await asyncio.sleep(1.0) mocked_logger_warning.assert_called_with( "Cannot connect to OEFChannel. Retrying in 5 seconds..." ) task.cancel() await asyncio.sleep(1.0)
def __init__(self, private_key_paths: Dict[str, str]): """ Instantiate a wallet object. :param private_key_paths: the private key paths """ crypto_objects = {} # type: Dict[str, Crypto] public_keys = {} # type: Dict[str, str] addresses = {} # type: Dict[str, str] for identifier, path in private_key_paths.items(): if identifier == DEFAULT: crypto_objects[identifier] = DefaultCrypto(path) elif identifier == FETCHAI: crypto_objects[identifier] = FetchAICrypto(path) elif identifier == ETHEREUM: crypto_objects[identifier] = EthereumCrypto(path) else: raise ValueError("Unsupported identifier in private key paths.") crypto = cast(Crypto, crypto_objects.get(identifier)) public_keys[identifier] = cast(str, crypto.public_key) addresses[identifier] = cast(str, crypto.address) self._crypto_objects = crypto_objects self._public_keys = public_keys self._addresses = addresses
def test_failed_transfer_fetchai(self): """Test the transfer function for fetchai token fails.""" private_key_path = os.path.join(CUR_PATH, "data", "fet_private_key.txt") fet_obj = FetchAICrypto(private_key_path=private_key_path) ledger_apis = LedgerApis( {ETHEREUM: DEFAULT_ETHEREUM_CONFIG, FETCHAI: DEFAULT_FETCHAI_CONFIG}, FETCHAI, ) with mock.patch.object( ledger_apis.apis.get(FETCHAI).api.tokens, "transfer", return_value="97fcacaaf94b62318c4e4bbf53fd2608c15062f17a6d1bffee0ba7af9b710e35", ): with mock.patch.object( ledger_apis.apis.get(FETCHAI).api, "sync", side_effect=Exception ): tx_digest = ledger_apis.transfer( fet_obj, fet_address, amount=10, tx_fee=10, tx_nonce="transaction nonce", ) assert tx_digest is None assert ledger_apis.last_tx_statuses[FETCHAI] == "ERROR"
async def test_cancelled_receive(network_node): """Test the case when a receive request is cancelled.""" address = FetchAICrypto().address oef_connection = OEFConnection( address=address, oef_addr="127.0.0.1", oef_port=10000, connection_id=PublicId("fetchai", "oef", "0.1.0"), ) oef_connection.loop = asyncio.get_event_loop() await oef_connection.connect() patch = unittest.mock.patch.object( packages.fetchai.connections.oef.connection.logger, "debug" ) mocked_logger_debug = patch.__enter__() async def receive(): await oef_connection.receive() task = asyncio.ensure_future(receive(), loop=asyncio.get_event_loop()) await asyncio.sleep(0.1) task.cancel() await asyncio.sleep(0.1) await oef_connection.disconnect() mocked_logger_debug.assert_called_once_with("Receive cancelled.")
def generate_key(ctx: Context, type_): """Generate private keys.""" if type_ == DefaultCrypto.identifier or type_ == "all": DefaultCrypto().dump(open(DEFAULT_PRIVATE_KEY_FILE, "wb")) if type_ == FetchAICrypto.identifier or type_ == "all": FetchAICrypto().dump(open(FETCHAI_PRIVATE_KEY_FILE, "wb")) if type_ == EthereumCrypto.identifier or type_ == "all": EthereumCrypto().dump(open(ETHEREUM_PRIVATE_KEY_FILE, "wb"))
def setup_class(cls): """Set the test up.""" cls.crypto1 = FetchAICrypto() cls.connection = _make_oef_connection( cls.crypto1.address, oef_addr="127.0.0.1", oef_port=10000, ) cls.multiplexer = Multiplexer([cls.connection]) cls.multiplexer.connect()
def test_get_balance(): """Test the balance is zero for a new account.""" fetchai_api = FetchAIApi(**FETCHAI_TESTNET_CONFIG) fc = FetchAICrypto() balance = fetchai_api.get_balance(fc.address) assert balance == 0, "New account has a positive balance." balance = get_wealth(fc.address) assert balance > 0, "Existing account has no balance."
def test_connection(self): """Test that an OEF connection can be established to the OEF.""" crypto = FetchAICrypto() connection = _make_oef_connection( crypto.address, oef_addr="127.0.0.1", oef_port=10000, ) multiplexer = Multiplexer([connection]) multiplexer.connect() multiplexer.disconnect()
def test_initialization(): """Test the initialisation of the variables.""" account = FetchAICrypto() assert account.entity is not None, "The property must return the account." assert (account.address is not None), "After creation the display address must not be None" assert account.address.startswith("fetch") assert (account.public_key is not None), "After creation the public key must no be None"
def test_get_wealth_positive(caplog): """Test the balance is zero for a new account.""" with caplog.at_level(logging.DEBUG, logger="aea.crypto.fetchai"): fetchai_faucet_api = FetchAIFaucetApi() fc = FetchAICrypto() fetchai_faucet_api.get_wealth(fc.address) assert ( "Message: Transfer pending" in caplog.text), f"Cannot find message in output: {caplog.text}"