def test_signed_transaction_encode_decode(): """Test encoding and decoding of signed_transaction.""" class SignedTransactionProtobufObject: signed_transaction_bytes = b"" ledger_id = "some_ledger" body = {"key": "value"} st = SignedTransaction(ledger_id, body) SignedTransaction.encode(SignedTransactionProtobufObject, st) recovered_st = SignedTransaction.decode(SignedTransactionProtobufObject) assert st == recovered_st
def _handle_transaction_signing( self, signing_msg: SigningMessage, signing_dialogue: SigningDialogue ) -> None: """ Handle a transaction for signing. :param signing_msg: the signing message :param signing_dialogue: the signing dialogue :return: None """ performative = self.signing_msg_class.Performative.ERROR kwargs = { "error_code": self.signing_msg_class.ErrorCode.UNSUCCESSFUL_TRANSACTION_SIGNING, } # type: Dict[str, Any] if self._is_acceptable_for_signing(signing_msg): signed_tx = self.wallet.sign_transaction( signing_msg.raw_transaction.ledger_id, signing_msg.raw_transaction.body ) if signed_tx is not None: performative = self.signing_msg_class.Performative.SIGNED_TRANSACTION kwargs.pop("error_code") kwargs["signed_transaction"] = SignedTransaction( signing_msg.raw_transaction.ledger_id, signed_tx ) signing_msg_response = signing_dialogue.reply( performative=performative, target_message=signing_msg, **kwargs, ) self.message_out_queue.put(signing_msg_response)
def test_init_signed_transaction(): """Test the signed_transaction object initialization.""" ledger_id = "some_ledger" body = "body" st = SignedTransaction(ledger_id, body) assert st.ledger_id == ledger_id assert st.body == body assert str(st) == "SignedTransaction: ledger_id=some_ledger, body=body" assert st == st
def test_init_signed_transaction(): """Test the signed_transaction object initialization.""" ledger_id = "some_ledger" body = {"key": "value"} st = SignedTransaction(ledger_id, body) assert st.ledger_id == ledger_id assert st.body == body assert str( st ) == "SignedTransaction: ledger_id=some_ledger, body={'key': 'value'}" assert st == st
def test_signed_transaction(self): """Test for an error for a signed transaction.""" tx_msg = SigningMessage( performative=SigningMessage.Performative.SIGNED_TRANSACTION, message_id=2, target=1, signed_transaction=SignedTransaction(self.ledger_id, "signature"), ) assert tx_msg._is_consistent() encoded_tx_msg = tx_msg.encode() decoded_tx_msg = tx_msg.serializer.decode(encoded_tx_msg) assert tx_msg == decoded_tx_msg
def test_handle_internal_messages(self): """Test that the internal messages are handled.""" t = SigningMessage( performative=SigningMessage.Performative.SIGNED_TRANSACTION, signed_transaction=SignedTransaction("ledger_id", "tx"), ) t.to = str(PublicId("dummy_author", "dummy", "0.1.0")) t.sender = "decision_maker" self.aea._filter.handle_internal_message(t) internal_handlers_list = self.aea.resources.get_handlers(t.protocol_id) assert len(internal_handlers_list) == 1 internal_handler = internal_handlers_list[0] assert len(internal_handler.handled_internal_messages) == 1 self.aea.teardown()
def test_message_consistency(self): """Test for an error in consistency of a message.""" tx_msg = SigningMessage( performative=SigningMessage.Performative.SIGN_TRANSACTION, skill_callback_ids=self.skill_callback_ids, skill_callback_info=self.skill_callback_info, terms=self.terms, raw_transaction=RawTransaction(self.ledger_id, "transaction"), ) assert tx_msg._is_consistent() tx_msg = SigningMessage( performative=SigningMessage.Performative.SIGN_MESSAGE, skill_callback_ids=self.skill_callback_ids, skill_callback_info=self.skill_callback_info, terms=self.terms, raw_message=RawMessage(self.ledger_id, "message"), ) assert tx_msg._is_consistent() tx_msg = SigningMessage( performative=SigningMessage.Performative.SIGNED_TRANSACTION, message_id=2, target=1, skill_callback_ids=self.skill_callback_ids, skill_callback_info=self.skill_callback_info, signed_transaction=SignedTransaction(self.ledger_id, "signature"), ) assert tx_msg._is_consistent() tx_msg = SigningMessage( performative=SigningMessage.Performative.SIGNED_MESSAGE, message_id=2, target=1, skill_callback_ids=self.skill_callback_ids, skill_callback_info=self.skill_callback_info, signed_message=SignedMessage(self.ledger_id, "message"), ) assert tx_msg._is_consistent() tx_msg = SigningMessage( performative=SigningMessage.Performative.ERROR, message_id=2, target=1, skill_callback_ids=self.skill_callback_ids, skill_callback_info=self.skill_callback_info, error_code=SigningMessage.ErrorCode.UNSUCCESSFUL_MESSAGE_SIGNING, ) assert tx_msg._is_consistent() assert str(tx_msg.performative) == "error" assert len(tx_msg.valid_performatives) == 5
def test_handle_internal_messages(self): """Test that the internal messages are handled.""" t = SigningMessage( performative=SigningMessage.Performative.SIGNED_TRANSACTION, skill_callback_ids=[str(PublicId("dummy_author", "dummy", "0.1.0"))], skill_callback_info={}, crypto_id="ledger_id", signed_transaction=SignedTransaction("ledger_id", "tx"), ) self.aea.decision_maker.message_out_queue.put(t) self.aea._filter.handle_internal_messages() internal_handlers_list = self.aea.resources.get_handlers(t.protocol_id) assert len(internal_handlers_list) == 1 internal_handler = internal_handlers_list[0] assert len(internal_handler.handled_internal_messages) == 1 self.aea.teardown()
def _handle_transaction_signing(self, signing_msg: SigningMessage, signing_dialogue: SigningDialogue) -> None: """ Handle a transaction for signing. :param signing_msg: the signing message :param signing_dialogue: the signing dialogue :return: None """ signing_msg_response = SigningMessage( performative=SigningMessage.Performative.ERROR, dialogue_reference=signing_dialogue.dialogue_label. dialogue_reference, target=signing_msg.message_id, message_id=signing_msg.message_id + 1, skill_callback_ids=signing_msg.skill_callback_ids, skill_callback_info=signing_msg.skill_callback_info, error_code=SigningMessage.ErrorCode. UNSUCCESSFUL_TRANSACTION_SIGNING, ) if self._is_acceptable_for_signing(signing_msg): signed_tx = self.wallet.sign_transaction( signing_msg.raw_transaction.ledger_id, signing_msg.raw_transaction.body) if signed_tx is not None: signing_msg_response = SigningMessage( performative=SigningMessage.Performative. SIGNED_TRANSACTION, dialogue_reference=signing_dialogue.dialogue_label. dialogue_reference, target=signing_msg.message_id, message_id=signing_msg.message_id + 1, skill_callback_ids=signing_msg.skill_callback_ids, skill_callback_info=signing_msg.skill_callback_info, signed_transaction=SignedTransaction( signing_msg.raw_transaction.ledger_id, signed_tx), ) signing_msg_response.counterparty = signing_msg.counterparty signing_dialogue.update(signing_msg_response) self.message_out_queue.put(signing_msg_response)
async def test_send_signed_transaction_ethereum( ledger_apis_connection: Connection): """Test send signed transaction with Ethereum APIs.""" import aea # noqa # to load registries crypto1 = EthereumCrypto(private_key_path=ETHEREUM_PRIVATE_KEY_PATH) crypto2 = EthereumCrypto() api = aea.crypto.registries.make_ledger_api(EthereumCrypto.identifier, **ETHEREUM_TESTNET_CONFIG) api = cast(EthereumApi, api) ledger_api_dialogues = LedgerApiDialogues() amount = 40000 fee = 30000 request = LedgerApiMessage( performative=LedgerApiMessage.Performative.GET_RAW_TRANSACTION, dialogue_reference=ledger_api_dialogues. new_self_initiated_dialogue_reference(), terms=Terms( ledger_id=EthereumCrypto.identifier, sender_address=crypto1.address, counterparty_address=crypto2.address, amount_by_currency_id={"ETH": -amount}, quantities_by_good_id={"some_service_id": 1}, is_sender_payable_tx_fee=True, nonce="", fee_by_currency_id={"ETH": fee}, chain_id=3, ), ) request.counterparty = str(ledger_apis_connection.connection_id) ledger_api_dialogue = ledger_api_dialogues.update(request) assert ledger_api_dialogue is not None envelope = Envelope( to=str(ledger_apis_connection.connection_id), sender=crypto1.address, protocol_id=request.protocol_id, message=request, ) await ledger_apis_connection.send(envelope) await asyncio.sleep(0.01) response = await ledger_apis_connection.receive() assert response is not None assert type(response.message) == LedgerApiMessage response_message = cast(LedgerApiMessage, response.message) assert (response_message.performative == LedgerApiMessage.Performative.RAW_TRANSACTION) response_dialogue = ledger_api_dialogues.update(response_message) assert response_dialogue == ledger_api_dialogue assert type(response_message.raw_transaction) == RawTransaction assert response_message.raw_transaction.ledger_id == request.terms.ledger_id # raw_tx = api.get_transfer_transaction( # sender_address=crypto1.address, # destination_address=crypto2.address, # amount=amount, # tx_fee=fee, # tx_nonce="", # chain_id=3, # ) signed_transaction = crypto1.sign_transaction( response_message.raw_transaction.body) request = LedgerApiMessage( performative=LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTION, dialogue_reference=ledger_api_dialogue.dialogue_label. dialogue_reference, signed_transaction=SignedTransaction(EthereumCrypto.identifier, signed_transaction), ) request.counterparty = str(ledger_apis_connection.connection_id) ledger_api_dialogue.update(request) envelope = Envelope( to=str(ledger_apis_connection.connection_id), sender=crypto1.address, protocol_id=request.protocol_id, message=request, ) await ledger_apis_connection.send(envelope) await asyncio.sleep(0.01) response = await ledger_apis_connection.receive() assert response is not None assert type(response.message) == LedgerApiMessage response_message = cast(LedgerApiMessage, response.message) assert (response_message.performative != LedgerApiMessage.Performative.ERROR ), f"Received error: {response_message.message}" assert (response_message.performative == LedgerApiMessage.Performative.TRANSACTION_DIGEST) response_dialogue = ledger_api_dialogues.update(response_message) assert response_dialogue == ledger_api_dialogue assert type(response_message.transaction_digest) == TransactionDigest assert type(response_message.transaction_digest.body) == str assert (response_message.transaction_digest.ledger_id == request.signed_transaction.ledger_id) assert type(response_message.transaction_digest.body.startswith("0x")) request = LedgerApiMessage( performative=LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT, dialogue_reference=ledger_api_dialogue.dialogue_label. dialogue_reference, transaction_digest=response_message.transaction_digest, ) request.counterparty = str(ledger_apis_connection.connection_id) ledger_api_dialogue.update(request) envelope = Envelope( to=str(ledger_apis_connection.connection_id), sender=crypto1.address, protocol_id=request.protocol_id, message=request, ) await ledger_apis_connection.send(envelope) await asyncio.sleep(0.01) response = await ledger_apis_connection.receive() assert response is not None assert type(response.message) == LedgerApiMessage response_message = cast(LedgerApiMessage, response.message) assert (response_message.performative == LedgerApiMessage.Performative.TRANSACTION_RECEIPT) response_dialogue = ledger_api_dialogues.update(response_message) assert response_dialogue == ledger_api_dialogue assert type(response_message.transaction_receipt) == TransactionReceipt assert response_message.transaction_receipt.receipt is not None assert response_message.transaction_receipt.transaction is not None assert (response_message.transaction_receipt.ledger_id == request.transaction_digest.ledger_id)
async def test_send_signed_transaction_ethereum( ledger_apis_connection: Connection): """Test send signed transaction with Ethereum APIs.""" import aea # noqa # to load registries crypto1 = make_crypto(ETHEREUM, private_key_path=ETHEREUM_PRIVATE_KEY_PATH) crypto2 = make_crypto(ETHEREUM) ledger_api_dialogues = LedgerApiDialogues(crypto1.address) amount = 40000 fee = 30000 request, ledger_api_dialogue = ledger_api_dialogues.create( counterparty=str(ledger_apis_connection.connection_id), performative=LedgerApiMessage.Performative.GET_RAW_TRANSACTION, terms=Terms( ledger_id=ETHEREUM, sender_address=crypto1.address, counterparty_address=crypto2.address, amount_by_currency_id={"ETH": -amount}, quantities_by_good_id={"some_service_id": 1}, is_sender_payable_tx_fee=True, nonce="", fee_by_currency_id={"ETH": fee}, chain_id=3, ), ) request = cast(LedgerApiMessage, request) envelope = Envelope( to=request.to, sender=request.sender, protocol_id=request.protocol_id, message=request, ) await ledger_apis_connection.send(envelope) await asyncio.sleep(0.01) response = await ledger_apis_connection.receive() assert response is not None assert type(response.message) == LedgerApiMessage response_message = cast(LedgerApiMessage, response.message) assert (response_message.performative == LedgerApiMessage.Performative.RAW_TRANSACTION) response_dialogue = ledger_api_dialogues.update(response_message) assert response_dialogue == ledger_api_dialogue assert type(response_message.raw_transaction) == RawTransaction assert response_message.raw_transaction.ledger_id == request.terms.ledger_id signed_transaction = crypto1.sign_transaction( response_message.raw_transaction.body) request = cast( LedgerApiMessage, ledger_api_dialogue.reply( performative=LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTION, target_message=response_message, signed_transaction=SignedTransaction(ETHEREUM, signed_transaction), ), ) envelope = Envelope( to=request.to, sender=request.sender, protocol_id=request.protocol_id, message=request, ) await ledger_apis_connection.send(envelope) await asyncio.sleep(0.01) response = await ledger_apis_connection.receive() assert response is not None assert type(response.message) == LedgerApiMessage response_message = cast(LedgerApiMessage, response.message) assert (response_message.performative != LedgerApiMessage.Performative.ERROR ), f"Received error: {response_message.message}" assert (response_message.performative == LedgerApiMessage.Performative.TRANSACTION_DIGEST) response_dialogue = ledger_api_dialogues.update(response_message) assert response_dialogue == ledger_api_dialogue assert type(response_message.transaction_digest) == TransactionDigest assert type(response_message.transaction_digest.body) == str assert (response_message.transaction_digest.ledger_id == request.signed_transaction.ledger_id) assert type(response_message.transaction_digest.body.startswith("0x")) request = cast( LedgerApiMessage, ledger_api_dialogue.reply( performative=LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT, target_message=response_message, transaction_digest=response_message.transaction_digest, ), ) envelope = Envelope( to=request.to, sender=request.sender, protocol_id=request.protocol_id, message=request, ) await ledger_apis_connection.send(envelope) await asyncio.sleep(0.01) response = await ledger_apis_connection.receive() assert response is not None assert type(response.message) == LedgerApiMessage response_message = cast(LedgerApiMessage, response.message) assert (response_message.performative == LedgerApiMessage.Performative.TRANSACTION_RECEIPT) response_dialogue = ledger_api_dialogues.update(response_message) assert response_dialogue == ledger_api_dialogue assert type(response_message.transaction_receipt) == TransactionReceipt assert response_message.transaction_receipt.receipt is not None assert response_message.transaction_receipt.transaction is not None assert (response_message.transaction_receipt.ledger_id == request.transaction_digest.ledger_id) assert LedgerApis.is_transaction_settled( response_message.transaction_receipt.ledger_id, response_message.transaction_receipt.receipt, ), "Transaction not settled."
def setup(cls): """Setup the test class.""" super().setup() cls.ledger_api_handler = cast( LedgerApiHandler, cls._skill.skill_context.handlers.ledger_api) cls.ledger_api_dialogues = cast( LedgerApiDialogues, cls._skill.skill_context.ledger_api_dialogues) cls.signing_dialogues = cast( SigningDialogues, cls._skill.skill_context.signing_dialogues) cls.contract_api_dialogues = cast( ContractApiDialogues, cls._skill.skill_context.contract_api_dialogues) cls.parameters = cast(Parameters, cls._skill.skill_context.parameters) cls.game = cast(Game, cls._skill.skill_context.game) cls.logger = cls.ledger_api_handler.context.logger cls.ledger_id = "some_ledger_id" cls.contract_id = "some_contract_id" cls.callable = "some_callable" cls.kwargs = Kwargs({"some_key": "some_value"}) cls.body = {"some_key": "some_value"} cls.body_str = "some_body" cls.contract_address = "some_contract_address" cls.raw_transaction = RawTransaction(cls.ledger_id, cls.body) cls.signed_transaction = SignedTransaction(cls.ledger_id, cls.body) cls.transaction_digest = TransactionDigest(cls.ledger_id, cls.body_str) cls.receipt = {"contractAddress": cls.contract_address} cls.transaction_receipt = TransactionReceipt( cls.ledger_id, cls.receipt, {"transaction_key": "transaction_value"}) cls.terms = Terms( cls.ledger_id, cls._skill.skill_context.agent_address, "counterprty", {"currency_id": 50}, {"good_id": -10}, "some_nonce", ) cls.list_of_signing_messages = (DialogueMessage( SigningMessage.Performative.SIGN_TRANSACTION, { "terms": cls.terms, "raw_transaction": SigningMessage.RawTransaction(cls.ledger_id, cls.body), }, ), ) cls.list_of_contract_api_messages = (DialogueMessage( ContractApiMessage.Performative.GET_DEPLOY_TRANSACTION, { "ledger_id": cls.ledger_id, "contract_id": cls.contract_id, "callable": cls.callable, "kwargs": cls.kwargs, }, ), ) cls.list_of_ledger_api_messages = ( DialogueMessage(LedgerApiMessage.Performative.GET_RAW_TRANSACTION, {"terms": cls.terms}), DialogueMessage( LedgerApiMessage.Performative.RAW_TRANSACTION, {"raw_transaction": cls.raw_transaction}, ), DialogueMessage( LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTION, {"signed_transaction": cls.signed_transaction}, ), DialogueMessage( LedgerApiMessage.Performative.TRANSACTION_DIGEST, {"transaction_digest": cls.transaction_digest}, ), DialogueMessage( LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT, {"transaction_digest": cls.transaction_digest}, ), )