From 68e631ebe346f734b7ded2c10c04d85764b4b293 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sa=C5=82aban?= Date: Wed, 31 Jan 2018 00:22:26 +0100 Subject: [PATCH] Test outgoing transfers --- monero/daemon.py | 4 +- tests/test_jsonrpcwallet.py | 333 ++++++++++++++++++++++++++++++++++-- 2 files changed, 324 insertions(+), 13 deletions(-) diff --git a/monero/daemon.py b/monero/daemon.py index 96152fe..4a290b6 100644 --- a/monero/daemon.py +++ b/monero/daemon.py @@ -8,8 +8,8 @@ class Daemon(object): def height(self): return self._backend.info()['height'] - def send_transaction(self, tx): - return self._backend.send_transaction(tx.blob) + def send_transaction(self, tx, relay=True): + return self._backend.send_transaction(tx.blob, relay=relay) def mempool(self): return self._backend.mempool() diff --git a/tests/test_jsonrpcwallet.py b/tests/test_jsonrpcwallet.py index 924642d..0f85d66 100644 --- a/tests/test_jsonrpcwallet.py +++ b/tests/test_jsonrpcwallet.py @@ -539,12 +539,108 @@ class SubaddrWalletTestCase(unittest.TestCase): 'id': 0, 'jsonrpc': '2.0', 'result': {'out': [{'address': '9tQoHWyZ4yXUgbz9nvMcFZUfDy5hxcdZabQCxmNCUukKYicXegsDL7nQpcUa3A1pF6K3fhq3scsyY88tdB1MqucULcKzWZC', + 'amount': 70000000000, + 'destinations': [{'address': 'BaB4Xsi9fBPDutsdNWTzNN5qgmTE2WUwnMGm5ukkb9TXUJHQLyZhQikekhHX8zhmRn3VTJeniuMXJHuCHfKyPk1XQDfk9bw', + 'amount': 70000000000}], + 'double_spend_seen': False, + 'fee': 960900000, + 'height': 1088441, + 'note': '', + 'payment_id': '0000000000000000', + 'subaddr_index': {'major': 0, 'minor': 0}, + 'timestamp': 1517342302, + 'txid': 'e32cccd7522e760b1c8a571fd08c75e7a1d822874380edc9656f58284eeb2fe5', + 'type': 'out', + 'unlock_time': 0}, + {'address': '9tQoHWyZ4yXUgbz9nvMcFZUfDy5hxcdZabQCxmNCUukKYicXegsDL7nQpcUa3A1pF6K3fhq3scsyY88tdB1MqucULcKzWZC', + 'amount': 21000000000000, + 'destinations': [{'address': 'BczAN2ZV5MENFAqSBdJJpzW9CMqURR9XTCjihzEGHzCV58YFRZHYuhk2huFsBrbPtDN2dGWHgiY1CRTUAPeDJg1ZFCzCssT', + 'amount': 21000000000000}], + 'double_spend_seen': False, + 'fee': 960990000, + 'height': 1088394, + 'note': '', + 'payment_id': '0000000000000000', + 'subaddr_index': {'major': 0, 'minor': 0}, + 'timestamp': 1517335388, + 'txid': 'edc7c28e7b07486be48dac0a178f25a3505114267ddaf3e62ab00d9a6e996044', + 'type': 'out', + 'unlock_time': 0}, + {'address': '9tQoHWyZ4yXUgbz9nvMcFZUfDy5hxcdZabQCxmNCUukKYicXegsDL7nQpcUa3A1pF6K3fhq3scsyY88tdB1MqucULcKzWZC', + 'amount': 210000000000, + 'destinations': [{'address': 'Bg2iRGq5f6iXf3gXYps9AJFWuhhtL74o8GE4JrBPFN3ViuyuTDcPSVqckGeNSU1brSFbdYJ5jjVerJ8Cb4aGJwJTSvzzHwf', + 'amount': 210000000000}], + 'double_spend_seen': False, + 'fee': 960810000, + 'height': 1088479, + 'note': '', + 'payment_id': '0000000000000000', + 'subaddr_index': {'major': 0, 'minor': 0}, + 'timestamp': 1517344830, + 'txid': 'd09666238129a1e2a71a9b7c6b30564a95baef926556bb658785cb9c38d9b25a', + 'type': 'out', + 'unlock_time': 0}, + {'address': '9tQoHWyZ4yXUgbz9nvMcFZUfDy5hxcdZabQCxmNCUukKYicXegsDL7nQpcUa3A1pF6K3fhq3scsyY88tdB1MqucULcKzWZC', + 'amount': 1111111111000, + 'double_spend_seen': False, + 'fee': 960750000, + 'height': 1088516, + 'note': '', + 'payment_id': '0000000000000000', + 'subaddr_index': {'major': 0, 'minor': 0}, + 'timestamp': 1517347450, + 'txid': '551721b5358b02565d6a9862867e3806b9a2e0d5aa5158d4d30940251d27bbdd', + 'type': 'out', + 'unlock_time': 0}, + {'address': '9tQoHWyZ4yXUgbz9nvMcFZUfDy5hxcdZabQCxmNCUukKYicXegsDL7nQpcUa3A1pF6K3fhq3scsyY88tdB1MqucULcKzWZC', + 'amount': 70000000000, + 'destinations': [{'address': 'BaB4Xsi9fBPDutsdNWTzNN5qgmTE2WUwnMGm5ukkb9TXUJHQLyZhQikekhHX8zhmRn3VTJeniuMXJHuCHfKyPk1XQDfk9bw', + 'amount': 70000000000}], + 'double_spend_seen': False, + 'fee': 960900000, + 'height': 1088438, + 'note': '', + 'payment_id': '0000000000000000', + 'subaddr_index': {'major': 0, 'minor': 0}, + 'timestamp': 1517341824, + 'txid': '21e7eb651e8a2bc7661975e965ac6b30a6f4033c6a02e96320e41139ad3e307c', + 'type': 'out', + 'unlock_time': 0}, + {'address': '9tQoHWyZ4yXUgbz9nvMcFZUfDy5hxcdZabQCxmNCUukKYicXegsDL7nQpcUa3A1pF6K3fhq3scsyY88tdB1MqucULcKzWZC', + 'amount': 3333333333330, + 'double_spend_seen': False, + 'fee': 960750000, + 'height': 1088521, + 'note': '', + 'payment_id': '0000000000000000', + 'subaddr_index': {'major': 0, 'minor': 0}, + 'timestamp': 1517347785, + 'txid': '5d15fef66fe8de715bcbf2c181f97b9932f9f843aef4724f3026fa3cd1082c68', + 'type': 'out', + 'unlock_time': 0}, + {'address': '9tQoHWyZ4yXUgbz9nvMcFZUfDy5hxcdZabQCxmNCUukKYicXegsDL7nQpcUa3A1pF6K3fhq3scsyY88tdB1MqucULcKzWZC', + 'amount': 1000000000000, + 'destinations': [{'address': 'Bg2iRGq5f6iXf3gXYps9AJFWuhhtL74o8GE4JrBPFN3ViuyuTDcPSVqckGeNSU1brSFbdYJ5jjVerJ8Cb4aGJwJTSvzzHwf', + 'amount': 1000000000000}], + 'double_spend_seen': False, + 'fee': 960990000, + 'height': 1088394, + 'note': '', + 'payment_id': '6cc9350927868849', + 'subaddr_index': {'major': 0, 'minor': 0}, + 'timestamp': 1517335388, + 'txid': '5e8f392a42899294e6b679ddac13cfe1dfe7f034b1e347424218af06c3dfdc85', + 'type': 'out', + 'unlock_time': 0}, + {'address': '9tQoHWyZ4yXUgbz9nvMcFZUfDy5hxcdZabQCxmNCUukKYicXegsDL7nQpcUa3A1pF6K3fhq3scsyY88tdB1MqucULcKzWZC', 'amount': 2450000000000, + 'destinations': [{'address': '9vgV48wWAPTWik5QSUSoGYicdvvsbSNHrT9Arsx1XBTz6VrWPSgfmnUKSPZDMyX4Ms8R9TkhB4uFqK9s5LUBbV6YQN2Q9ag', + 'amount': 2450000000000}], 'double_spend_seen': False, 'fee': 961350000, 'height': 1088184, 'note': '', - 'payment_id': '0000000000000000', + 'payment_id': '6cc9350927868849', 'subaddr_index': {'major': 0, 'minor': 0}, 'timestamp': 1517299877, 'txid': '2b41226d45edb875634694fccd95f3c174daa5062763eee619ed4475a7b9207a', @@ -552,6 +648,8 @@ class SubaddrWalletTestCase(unittest.TestCase): 'unlock_time': 0}, {'address': '9tQoHWyZ4yXUgbz9nvMcFZUfDy5hxcdZabQCxmNCUukKYicXegsDL7nQpcUa3A1pF6K3fhq3scsyY88tdB1MqucULcKzWZC', 'amount': 1000000000000, + 'destinations': [{'address': 'BZHa2Fm9yn3by1CWTBruWxEuZ5TqyMLiBQAFrHM6aniLfjTBWkA4E4kif63YS7wmbFW5UBwrFSKNoiSQ2mE8SS5S6uzgvoc', + 'amount': 1000000000000}], 'double_spend_seen': False, 'fee': 961350000, 'height': 1088184, @@ -563,19 +661,69 @@ class SubaddrWalletTestCase(unittest.TestCase): 'type': 'out', 'unlock_time': 0}, {'address': '9tQoHWyZ4yXUgbz9nvMcFZUfDy5hxcdZabQCxmNCUukKYicXegsDL7nQpcUa3A1pF6K3fhq3scsyY88tdB1MqucULcKzWZC', - 'amount': 1000000000000, + 'amount': 123000000000, + 'destinations': [{'address': 'BYeK7sZ9DhkASZpMrhGw6yFynaDy5PJ8T2CeogvGTFfT2kMQdTNJFQpDXpoHNBPTyNfrxERdRje9bBJh7LTqN4oDUVVvzAe', + 'amount': 123000000000}], 'double_spend_seen': False, - 'fee': 960990000, - 'height': 1088394, + 'fee': 3843000000, + 'height': 1088523, 'note': '', 'payment_id': '0000000000000000', 'subaddr_index': {'major': 0, 'minor': 0}, - 'timestamp': 1517335388, - 'txid': '5e8f392a42899294e6b679ddac13cfe1dfe7f034b1e347424218af06c3dfdc85', + 'timestamp': 1517347908, + 'txid': 'e291fe40c6102a6193c82ac33227c08e5b30a863dba1bc63e13043a25abbb97a', + 'type': 'out', + 'unlock_time': 0}, + {'address': '9tQoHWyZ4yXUgbz9nvMcFZUfDy5hxcdZabQCxmNCUukKYicXegsDL7nQpcUa3A1pF6K3fhq3scsyY88tdB1MqucULcKzWZC', + 'amount': 2220000000000, + 'double_spend_seen': False, + 'fee': 3843840000, + 'height': 1088411, + 'note': '', + 'payment_id': '0000000000000000', + 'subaddr_index': {'major': 0, 'minor': 0}, + 'timestamp': 1517339862, + 'txid': 'a8829744952facbfdaab21ca193298edb1fa16f688cd5dbcdff3ed3968155f28', + 'type': 'out', + 'unlock_time': 0}]}} + pay_out = self.wallet.outgoing() + self.assertEqual(len(list(pay_out)), 11) + for pmt in pay_out: + self.assertIsInstance(pmt, OutgoingPayment) + self.assertIsInstance(pmt.local_address, Address) + self.assertIsInstance(pmt.amount, Decimal) + self.assertIsInstance(pmt.timestamp, datetime) + self.assertIsInstance(pmt.transaction, Transaction) + self.assertIsInstance(pmt.transaction.fee, Decimal) + self.assertIsInstance(pmt.transaction.height, int) + + @patch('monero.backends.jsonrpc.requests.post') + def test_outgoing_confirmed_and_unconfirmed(self, mock_post): + mock_post.return_value.status_code = 200 + mock_post.return_value.json.return_value = self.accounts_result + self.wallet = Wallet(JSONRPCWallet()) + mock_post.return_value.status_code = 200 + mock_post.return_value.json.return_value = { + 'id': 0, + 'jsonrpc': '2.0', + 'result': {'out': [{'address': '9tQoHWyZ4yXUgbz9nvMcFZUfDy5hxcdZabQCxmNCUukKYicXegsDL7nQpcUa3A1pF6K3fhq3scsyY88tdB1MqucULcKzWZC', + 'amount': 70000000000, + 'destinations': [{'address': 'BaB4Xsi9fBPDutsdNWTzNN5qgmTE2WUwnMGm5ukkb9TXUJHQLyZhQikekhHX8zhmRn3VTJeniuMXJHuCHfKyPk1XQDfk9bw', + 'amount': 70000000000}], + 'double_spend_seen': False, + 'fee': 960900000, + 'height': 1088441, + 'note': '', + 'payment_id': '0000000000000000', + 'subaddr_index': {'major': 0, 'minor': 0}, + 'timestamp': 1517342302, + 'txid': 'e32cccd7522e760b1c8a571fd08c75e7a1d822874380edc9656f58284eeb2fe5', 'type': 'out', 'unlock_time': 0}, {'address': '9tQoHWyZ4yXUgbz9nvMcFZUfDy5hxcdZabQCxmNCUukKYicXegsDL7nQpcUa3A1pF6K3fhq3scsyY88tdB1MqucULcKzWZC', 'amount': 21000000000000, + 'destinations': [{'address': 'BczAN2ZV5MENFAqSBdJJpzW9CMqURR9XTCjihzEGHzCV58YFRZHYuhk2huFsBrbPtDN2dGWHgiY1CRTUAPeDJg1ZFCzCssT', + 'amount': 21000000000000}], 'double_spend_seen': False, 'fee': 960990000, 'height': 1088394, @@ -585,9 +733,141 @@ class SubaddrWalletTestCase(unittest.TestCase): 'timestamp': 1517335388, 'txid': 'edc7c28e7b07486be48dac0a178f25a3505114267ddaf3e62ab00d9a6e996044', 'type': 'out', - 'unlock_time': 0}]}} - pay_out = self.wallet.outgoing() - self.assertEqual(len(list(pay_out)), 4) + 'unlock_time': 0}, + {'address': '9tQoHWyZ4yXUgbz9nvMcFZUfDy5hxcdZabQCxmNCUukKYicXegsDL7nQpcUa3A1pF6K3fhq3scsyY88tdB1MqucULcKzWZC', + 'amount': 210000000000, + 'destinations': [{'address': 'Bg2iRGq5f6iXf3gXYps9AJFWuhhtL74o8GE4JrBPFN3ViuyuTDcPSVqckGeNSU1brSFbdYJ5jjVerJ8Cb4aGJwJTSvzzHwf', + 'amount': 210000000000}], + 'double_spend_seen': False, + 'fee': 960810000, + 'height': 1088479, + 'note': '', + 'payment_id': '0000000000000000', + 'subaddr_index': {'major': 0, 'minor': 0}, + 'timestamp': 1517344830, + 'txid': 'd09666238129a1e2a71a9b7c6b30564a95baef926556bb658785cb9c38d9b25a', + 'type': 'out', + 'unlock_time': 0}, + {'address': '9tQoHWyZ4yXUgbz9nvMcFZUfDy5hxcdZabQCxmNCUukKYicXegsDL7nQpcUa3A1pF6K3fhq3scsyY88tdB1MqucULcKzWZC', + 'amount': 1111111111000, + 'double_spend_seen': False, + 'fee': 960750000, + 'height': 1088516, + 'note': '', + 'payment_id': '0000000000000000', + 'subaddr_index': {'major': 0, 'minor': 0}, + 'timestamp': 1517347450, + 'txid': '551721b5358b02565d6a9862867e3806b9a2e0d5aa5158d4d30940251d27bbdd', + 'type': 'out', + 'unlock_time': 0}, + {'address': '9tQoHWyZ4yXUgbz9nvMcFZUfDy5hxcdZabQCxmNCUukKYicXegsDL7nQpcUa3A1pF6K3fhq3scsyY88tdB1MqucULcKzWZC', + 'amount': 70000000000, + 'destinations': [{'address': 'BaB4Xsi9fBPDutsdNWTzNN5qgmTE2WUwnMGm5ukkb9TXUJHQLyZhQikekhHX8zhmRn3VTJeniuMXJHuCHfKyPk1XQDfk9bw', + 'amount': 70000000000}], + 'double_spend_seen': False, + 'fee': 960900000, + 'height': 1088438, + 'note': '', + 'payment_id': '0000000000000000', + 'subaddr_index': {'major': 0, 'minor': 0}, + 'timestamp': 1517341824, + 'txid': '21e7eb651e8a2bc7661975e965ac6b30a6f4033c6a02e96320e41139ad3e307c', + 'type': 'out', + 'unlock_time': 0}, + {'address': '9tQoHWyZ4yXUgbz9nvMcFZUfDy5hxcdZabQCxmNCUukKYicXegsDL7nQpcUa3A1pF6K3fhq3scsyY88tdB1MqucULcKzWZC', + 'amount': 3333333333330, + 'double_spend_seen': False, + 'fee': 960750000, + 'height': 1088521, + 'note': '', + 'payment_id': '0000000000000000', + 'subaddr_index': {'major': 0, 'minor': 0}, + 'timestamp': 1517347785, + 'txid': '5d15fef66fe8de715bcbf2c181f97b9932f9f843aef4724f3026fa3cd1082c68', + 'type': 'out', + 'unlock_time': 0}, + {'address': '9tQoHWyZ4yXUgbz9nvMcFZUfDy5hxcdZabQCxmNCUukKYicXegsDL7nQpcUa3A1pF6K3fhq3scsyY88tdB1MqucULcKzWZC', + 'amount': 1000000000000, + 'destinations': [{'address': 'Bg2iRGq5f6iXf3gXYps9AJFWuhhtL74o8GE4JrBPFN3ViuyuTDcPSVqckGeNSU1brSFbdYJ5jjVerJ8Cb4aGJwJTSvzzHwf', + 'amount': 1000000000000}], + 'double_spend_seen': False, + 'fee': 960990000, + 'height': 1088394, + 'note': '', + 'payment_id': '6cc9350927868849', + 'subaddr_index': {'major': 0, 'minor': 0}, + 'timestamp': 1517335388, + 'txid': '5e8f392a42899294e6b679ddac13cfe1dfe7f034b1e347424218af06c3dfdc85', + 'type': 'out', + 'unlock_time': 0}, + {'address': '9tQoHWyZ4yXUgbz9nvMcFZUfDy5hxcdZabQCxmNCUukKYicXegsDL7nQpcUa3A1pF6K3fhq3scsyY88tdB1MqucULcKzWZC', + 'amount': 2450000000000, + 'destinations': [{'address': '9vgV48wWAPTWik5QSUSoGYicdvvsbSNHrT9Arsx1XBTz6VrWPSgfmnUKSPZDMyX4Ms8R9TkhB4uFqK9s5LUBbV6YQN2Q9ag', + 'amount': 2450000000000}], + 'double_spend_seen': False, + 'fee': 961350000, + 'height': 1088184, + 'note': '', + 'payment_id': '6cc9350927868849', + 'subaddr_index': {'major': 0, 'minor': 0}, + 'timestamp': 1517299877, + 'txid': '2b41226d45edb875634694fccd95f3c174daa5062763eee619ed4475a7b9207a', + 'type': 'out', + 'unlock_time': 0}, + {'address': '9tQoHWyZ4yXUgbz9nvMcFZUfDy5hxcdZabQCxmNCUukKYicXegsDL7nQpcUa3A1pF6K3fhq3scsyY88tdB1MqucULcKzWZC', + 'amount': 1000000000000, + 'destinations': [{'address': 'BZHa2Fm9yn3by1CWTBruWxEuZ5TqyMLiBQAFrHM6aniLfjTBWkA4E4kif63YS7wmbFW5UBwrFSKNoiSQ2mE8SS5S6uzgvoc', + 'amount': 1000000000000}], + 'double_spend_seen': False, + 'fee': 961350000, + 'height': 1088184, + 'note': '', + 'payment_id': '0000000000000000', + 'subaddr_index': {'major': 0, 'minor': 0}, + 'timestamp': 1517299877, + 'txid': '40de45db57eb87eb8395baf5c1dc705602938317d043f463e68ed85b7108f9f3', + 'type': 'out', + 'unlock_time': 0}, + {'address': '9tQoHWyZ4yXUgbz9nvMcFZUfDy5hxcdZabQCxmNCUukKYicXegsDL7nQpcUa3A1pF6K3fhq3scsyY88tdB1MqucULcKzWZC', + 'amount': 123000000000, + 'destinations': [{'address': 'BYeK7sZ9DhkASZpMrhGw6yFynaDy5PJ8T2CeogvGTFfT2kMQdTNJFQpDXpoHNBPTyNfrxERdRje9bBJh7LTqN4oDUVVvzAe', + 'amount': 123000000000}], + 'double_spend_seen': False, + 'fee': 3843000000, + 'height': 1088523, + 'note': '', + 'payment_id': '0000000000000000', + 'subaddr_index': {'major': 0, 'minor': 0}, + 'timestamp': 1517347908, + 'txid': 'e291fe40c6102a6193c82ac33227c08e5b30a863dba1bc63e13043a25abbb97a', + 'type': 'out', + 'unlock_time': 0}, + {'address': '9tQoHWyZ4yXUgbz9nvMcFZUfDy5hxcdZabQCxmNCUukKYicXegsDL7nQpcUa3A1pF6K3fhq3scsyY88tdB1MqucULcKzWZC', + 'amount': 2220000000000, + 'double_spend_seen': False, + 'fee': 3843840000, + 'height': 1088411, + 'note': '', + 'payment_id': '0000000000000000', + 'subaddr_index': {'major': 0, 'minor': 0}, + 'timestamp': 1517339862, + 'txid': 'a8829744952facbfdaab21ca193298edb1fa16f688cd5dbcdff3ed3968155f28', + 'type': 'out', + 'unlock_time': 0}], + 'pending': [{'address': '9tQoHWyZ4yXUgbz9nvMcFZUfDy5hxcdZabQCxmNCUukKYicXegsDL7nQpcUa3A1pF6K3fhq3scsyY88tdB1MqucULcKzWZC', + 'amount': 3141592653589, + 'double_spend_seen': False, + 'fee': 3842880000, + 'height': 0, + 'note': '', + 'payment_id': '0000000000000000000000000000000079323846264338327950288419716939', + 'subaddr_index': {'major': 0, 'minor': 0}, + 'timestamp': 1517348994, + 'txid': '34833fef78c7b7c15383a78912344ecfb3ace479d27c4bd6f3e3f136ddc1d6a9', + 'type': 'pending', + 'unlock_time': 0}]}} + pay_out = self.wallet.outgoing(unconfirmed=True) + self.assertEqual(len(list(pay_out)), 12) for pmt in pay_out: self.assertIsInstance(pmt, OutgoingPayment) self.assertIsInstance(pmt.local_address, Address) @@ -595,8 +875,39 @@ class SubaddrWalletTestCase(unittest.TestCase): self.assertIsInstance(pmt.timestamp, datetime) self.assertIsInstance(pmt.transaction, Transaction) self.assertIsInstance(pmt.transaction.fee, Decimal) - self.assertIsInstance(pmt.transaction.height, int) - self.assertEqual(pmt.note, '') + self.assertIsInstance(pmt.transaction.height, (int, type(None))) + + @patch('monero.backends.jsonrpc.requests.post') + def test_outgoing_unconfirmed_only(self, mock_post): + mock_post.return_value.status_code = 200 + mock_post.return_value.json.return_value = self.accounts_result + self.wallet = Wallet(JSONRPCWallet()) + mock_post.return_value.status_code = 200 + mock_post.return_value.json.return_value = { + 'id': 0, + 'jsonrpc': '2.0', + 'result': {'pending': [{'address': '9tQoHWyZ4yXUgbz9nvMcFZUfDy5hxcdZabQCxmNCUukKYicXegsDL7nQpcUa3A1pF6K3fhq3scsyY88tdB1MqucULcKzWZC', + 'amount': 3141592653589, + 'double_spend_seen': False, + 'fee': 3842880000, + 'height': 0, + 'note': '', + 'payment_id': '0000000000000000000000000000000079323846264338327950288419716939', + 'subaddr_index': {'major': 0, 'minor': 0}, + 'timestamp': 1517348994, + 'txid': '34833fef78c7b7c15383a78912344ecfb3ace479d27c4bd6f3e3f136ddc1d6a9', + 'type': 'pending', + 'unlock_time': 0}]}} + pay_out = self.wallet.outgoing(unconfirmed=True, confirmed=False) + self.assertEqual(len(list(pay_out)), 1) + for pmt in pay_out: + self.assertIsInstance(pmt, OutgoingPayment) + self.assertIsInstance(pmt.local_address, Address) + self.assertIsInstance(pmt.amount, Decimal) + self.assertIsInstance(pmt.timestamp, datetime) + self.assertIsInstance(pmt.transaction, Transaction) + self.assertIsInstance(pmt.transaction.fee, Decimal) + self.assertIs(pmt.transaction.height, None) @patch('monero.backends.jsonrpc.requests.post') def test_send_transfer(self, mock_post):