def test_submit_earn_batch_with_invoices(self, grpc_channel, executor, app_index_client): sender = PrivateKey.random() earns = [ Earn(PrivateKey.random().public_key, 100000, invoice=Invoice([LineItem('title1', 100000, 'description1', b'somesku')])), Earn(PrivateKey.random().public_key, 100000, invoice=Invoice([LineItem('title2', 100000, 'description2', b'somesku')])), ] future = executor.submit(app_index_client.submit_earn_batch, sender, earns) account_req = self._set_successful_get_account_info_response(grpc_channel, sender, 10) result_xdr = gen_result_xdr(xdr_const.txSUCCESS, [gen_payment_op_result(xdr_const.PAYMENT_SUCCESS)]) submit_req = self._set_successful_submit_transaction_response(grpc_channel, b'somehash', result_xdr) batch_earn_result = future.result() assert len(batch_earn_result.succeeded) == 2 assert len(batch_earn_result.failed) == 0 for idx, earn_result in enumerate(batch_earn_result.succeeded): assert earn_result.tx_hash == b'somehash' assert earn_result.earn == earns[idx] assert not earn_result.error assert account_req.account_id.value == sender.public_key.stellar_address il = InvoiceList([earn.invoice for earn in earns]) expected_memo = memo.HashMemo(AgoraMemo.new(1, TransactionType.EARN, 1, il.get_sha_224_hash()).val) self._assert_earn_batch_envelope(submit_req.envelope_xdr, [sender], sender, 100, 11, expected_memo, sender, earns) assert len(submit_req.invoice_list.invoices) == 2 assert submit_req.invoice_list.SerializeToString() == il.to_proto().SerializeToString()
def test_submit_earn_batch_rejected(self, grpc_channel, executor, app_index_client): sender = PrivateKey.random() earns = [ Earn(PrivateKey.random().public_key, 100000), Earn(PrivateKey.random().public_key, 100000), ] future = executor.submit(app_index_client.submit_earn_batch, sender, earns) account_req = self._set_successful_get_account_info_response(grpc_channel, sender, 10) resp = tx_pb.SubmitTransactionResponse( result=tx_pb.SubmitTransactionResponse.Result.REJECTED, hash=model_pb2.TransactionHash(value=b'somehash'), ) submit_req = self._set_submit_transaction_response(grpc_channel, resp) batch_earn_result = future.result() assert len(batch_earn_result.succeeded) == 0 assert len(batch_earn_result.failed) == 2 for idx, earn_result in enumerate(batch_earn_result.failed): assert earn_result.earn == earns[idx] assert not earn_result.tx_hash assert isinstance(earn_result.error, TransactionRejectedError) assert account_req.account_id.value == sender.public_key.stellar_address expected_memo = memo.HashMemo(AgoraMemo.new(1, TransactionType.EARN, 1, b'').val) self._assert_earn_batch_envelope(submit_req.envelope_xdr, [sender], sender, 100, 11, expected_memo, sender, earns) assert len(submit_req.invoice_list.invoices) == 0
def test_submit_earn_batch_with_some_invoices(self, grpc_channel, executor, app_index_client): sender = PrivateKey.random() earns = [ Earn(PrivateKey.random().public_key, 100000, invoice=Invoice([LineItem('title1', 100000, 'description1', b'somesku')])), Earn(PrivateKey.random().public_key, 100000), ] future = executor.submit(app_index_client.submit_earn_batch, sender, earns) with pytest.raises(ValueError): future.result()
def test_submit_earn_batch_invoice_error(self, grpc_channel, executor, app_index_client): sender = PrivateKey.random() earns = [ Earn(PrivateKey.random().public_key, 100000, invoice=Invoice([LineItem('title1', 100000, 'description1', b'somesku')])), Earn(PrivateKey.random().public_key, 100000, invoice=Invoice([LineItem('title1', 100000, 'description1', b'somesku')])), ] future = executor.submit(app_index_client.submit_earn_batch, sender, earns) account_req = self._set_successful_get_account_info_response(grpc_channel, sender, 10) resp = tx_pb.SubmitTransactionResponse( result=tx_pb.SubmitTransactionResponse.Result.INVOICE_ERROR, invoice_errors=[ tx_pb.SubmitTransactionResponse.InvoiceError( op_index=0, invoice=earns[0].invoice.to_proto(), reason=tx_pb.SubmitTransactionResponse.InvoiceError.Reason.ALREADY_PAID, ), tx_pb.SubmitTransactionResponse.InvoiceError( op_index=0, invoice=earns[1].invoice.to_proto(), reason=tx_pb.SubmitTransactionResponse.InvoiceError.Reason.WRONG_DESTINATION, ) ] ) submit_req = self._set_submit_transaction_response(grpc_channel, resp) batch_earn_result = future.result() assert len(batch_earn_result.succeeded) == 0 assert len(batch_earn_result.failed) == 2 for idx, earn_result in enumerate(batch_earn_result.failed): assert earn_result.earn == earns[idx] assert not earn_result.tx_hash assert isinstance(earn_result.error, Error) assert account_req.account_id.value == sender.public_key.stellar_address expected_memo = memo.HashMemo( AgoraMemo.new(1, TransactionType.EARN, 1, InvoiceList([earn.invoice for earn in earns]).get_sha_224_hash()).val) self._assert_earn_batch_envelope(submit_req.envelope_xdr, [sender], sender, 100, 11, expected_memo, sender, earns) assert len(submit_req.invoice_list.invoices) == 2 assert (submit_req.invoice_list.invoices[0].SerializeToString() == earns[0].invoice.to_proto().SerializeToString()) assert (submit_req.invoice_list.invoices[1].SerializeToString() == earns[1].invoice.to_proto().SerializeToString())
def test_submit_earn_batch_with_memo(self, grpc_channel, executor, app_index_client): sender = PrivateKey.random() earns = [Earn(PrivateKey.random().public_key, 100000)] future = executor.submit(app_index_client.submit_earn_batch, sender, earns, memo="somememo") account_req = self._set_successful_get_account_info_response(grpc_channel, sender, 10) result_xdr = gen_result_xdr(xdr_const.txSUCCESS, [gen_payment_op_result(xdr_const.PAYMENT_SUCCESS)]) submit_req = self._set_successful_submit_transaction_response(grpc_channel, b'somehash', result_xdr) batch_earn_result = future.result() assert len(batch_earn_result.succeeded) == 1 assert len(batch_earn_result.failed) == 0 earn_result = batch_earn_result.succeeded[0] assert earn_result.earn == earns[0] assert earn_result.tx_hash == b'somehash' assert not earn_result.error assert account_req.account_id.value == sender.public_key.stellar_address expected_memo = memo.TextMemo('somememo') self._assert_earn_batch_envelope(submit_req.envelope_xdr, [sender], sender, 100, 11, expected_memo, sender, earns) assert len(submit_req.invoice_list.invoices) == 0
def test_submit_earn_batch_with_whitelisting(self, grpc_channel, executor, whitelisting_client): sender = PrivateKey.random() earns = [Earn(PrivateKey.random().public_key, 100000)] future = executor.submit(whitelisting_client.submit_earn_batch, sender, earns) account_req = self._set_successful_get_account_info_response(grpc_channel, sender, 10) result_xdr = gen_result_xdr(xdr_const.txSUCCESS, [gen_payment_op_result(xdr_const.PAYMENT_SUCCESS)]) submit_req = self._set_successful_submit_transaction_response(grpc_channel, b'somehash', result_xdr) batch_earn_result = future.result() assert len(batch_earn_result.succeeded) == 1 assert len(batch_earn_result.failed) == 0 earn_result = batch_earn_result.succeeded[0] assert earn_result.earn == earns[0] assert earn_result.tx_hash == b'somehash' assert not earn_result.error assert account_req.account_id.value == sender.public_key.stellar_address expected_signers = [sender, whitelisting_client.whitelist_key] expected_memo = memo.HashMemo(AgoraMemo.new(1, TransactionType.EARN, 1, b'').val) self._assert_earn_batch_envelope(submit_req.envelope_xdr, expected_signers, sender, 100, 11, expected_memo, sender, earns)
def test_submit_earn_batch_multiple(self, grpc_channel, executor, app_index_client): sender = PrivateKey.random() all_earns = [Earn(PrivateKey.random().public_key, i) for i in range(250)] future = executor.submit(app_index_client.submit_earn_batch, sender, all_earns) account_reqs = [] submit_reqs = [] tx_hashes = [] result_xdr = gen_result_xdr(xdr_const.txSUCCESS, [gen_payment_op_result(xdr_const.PAYMENT_SUCCESS)]) starting_seq = 10 for i in range(3): account_reqs.append(self._set_successful_get_account_info_response(grpc_channel, sender, starting_seq + i)) tx_hash = 'somehash{}'.format(i).encode() submit_reqs.append(self._set_successful_submit_transaction_response(grpc_channel, tx_hash, result_xdr)) tx_hashes.append(tx_hash) batch_earn_result = future.result() assert len(batch_earn_result.succeeded) == 250 assert len(batch_earn_result.failed) == 0 for account_req in account_reqs: assert account_req.account_id.value == sender.public_key.stellar_address earn_batches = partition(all_earns, 100) for idx, submit_req in enumerate(submit_reqs): expected_memo = memo.HashMemo(AgoraMemo.new(1, TransactionType.EARN, 1, b'').val) self._assert_earn_batch_envelope(submit_req.envelope_xdr, [sender], sender, 100, starting_seq + idx + 1, expected_memo, sender, earn_batches[idx]) assert len(submit_req.invoice_list.invoices) == 0
def test_submit_earn_batch_tx_failed(self, grpc_channel, executor, app_index_client): sender = PrivateKey.random() earns = [ Earn(PrivateKey.random().public_key, 100000), Earn(PrivateKey.random().public_key, 100000), ] future = executor.submit(app_index_client.submit_earn_batch, sender, earns) account_req = self._set_successful_get_account_info_response(grpc_channel, sender, 10) result_xdr = gen_result_xdr(xdr_const.txFAILED, [gen_payment_op_result(xdr_const.PAYMENT_UNDERFUNDED), gen_payment_op_result(xdr_const.PAYMENT_NO_DESTINATION)]) resp = tx_pb.SubmitTransactionResponse( result=tx_pb.SubmitTransactionResponse.Result.FAILED, hash=model_pb2.TransactionHash(value=b'somehash'), ledger=10, result_xdr=result_xdr, ) submit_req = self._set_submit_transaction_response(grpc_channel, resp) batch_earn_result = future.result() assert len(batch_earn_result.succeeded) == 0 assert len(batch_earn_result.failed) == 2 expected_errors = [InsufficientBalanceError, DestinationDoesNotExistError] for idx, earn_result in enumerate(batch_earn_result.failed): assert earn_result.earn == earns[idx] assert earn_result.tx_hash # make sure it's set assert isinstance(earn_result.error, expected_errors[idx]) assert account_req.account_id.value == sender.public_key.stellar_address expected_memo = memo.HashMemo(AgoraMemo.new(1, TransactionType.EARN, 1, b'').val) self._assert_earn_batch_envelope(submit_req.envelope_xdr, [sender], sender, 100, 11, expected_memo, sender, earns) assert len(submit_req.invoice_list.invoices) == 0
def test_submit_earn_batch_with_nonce_retry(self, grpc_channel, executor, nonce_retry_client): sender = PrivateKey.random() earns = [Earn(PrivateKey.random().public_key, 100000)] future = executor.submit(nonce_retry_client.submit_earn_batch, sender, earns) result_xdr = gen_result_xdr(xdr_const.txBAD_SEQ, []) resp = tx_pb.SubmitTransactionResponse( result=tx_pb.SubmitTransactionResponse.Result.FAILED, hash=model_pb2.TransactionHash(value=b'somehash'), ledger=10, result_xdr=result_xdr, ) account_reqs = [] submit_reqs = [] for i in range(_config_with_nonce_retry.max_nonce_refreshes + 1): # this blocks until the system under test invokes the RPC, so if the test completes then the RPC was called # the expected number of times. account_reqs.append(self._set_successful_get_account_info_response(grpc_channel, sender, 10)) submit_reqs.append(self._set_submit_transaction_response(grpc_channel, resp)) batch_earn_result = future.result() assert len(batch_earn_result.succeeded) == 0 assert len(batch_earn_result.failed) == 1 earn_result = batch_earn_result.failed[0] assert not earn_result.tx_hash assert earn_result.earn == earns[0] assert isinstance(earn_result.error, BadNonceError) for account_req in account_reqs: assert account_req.account_id.value == sender.public_key.stellar_address expected_memo = memo.HashMemo(AgoraMemo.new(1, TransactionType.EARN, 1, b'').val) for submit_req in submit_reqs: self._assert_earn_batch_envelope(submit_req.envelope_xdr, [sender], sender, 100, 11, expected_memo, sender, earns) assert len(submit_req.invoice_list.invoices) == 0
def test_submit_earn_batch_same_dest(self, grpc_channel, executor, app_index_client): sender = PrivateKey.random() dest = PrivateKey.random().public_key all_earns = [Earn(dest, i) for i in range(5)] future = executor.submit(app_index_client.submit_earn_batch, sender, all_earns) result_xdr = gen_result_xdr(xdr_const.txSUCCESS, [gen_payment_op_result(xdr_const.PAYMENT_SUCCESS)]) account_req = self._set_successful_get_account_info_response(grpc_channel, sender, 10) tx_hash = 'somehash'.encode() submit_req = self._set_successful_submit_transaction_response(grpc_channel, tx_hash, result_xdr) batch_earn_result = future.result() assert len(batch_earn_result.succeeded) == 5 assert len(batch_earn_result.failed) == 0 assert account_req.account_id.value == sender.public_key.stellar_address expected_memo = memo.HashMemo(AgoraMemo.new(1, TransactionType.EARN, 1, b'').val) self._assert_earn_batch_envelope(submit_req.envelope_xdr, [sender], sender, 100, 11, expected_memo, sender, all_earns) assert len(submit_req.invoice_list.invoices) == 0