Compare commits

...

7 Commits

Author SHA1 Message Date
Michał Sałaban d24044a5e7 Add security update message
2 years ago
Michał Sałaban 8d473e7381 Bump up version
2 years ago
Michał Sałaban a64bef178f Add contributors
2 years ago
j-berman ece5b9d4cd Verify commitment == yG + bH
2 years ago
Michał Sałaban 00c0955989 Add tests on garbled ecdhInfo field
2 years ago
Michał Sałaban 3aac154dde Update black
2 years ago
Michał Sałaban da200d2f33 Update requirements
2 years ago

@ -1,5 +1,5 @@
[bumpversion]
current_version = 1.0.1
current_version = 1.0.2
parse = (?P<major>\d+)\.(?P<minor>\d+)(?:\.(?P<patch>\d+))?
serialize =
{major}.{minor}.{patch}

@ -2,7 +2,7 @@ exclude:
^(build/|dist/|docs/|htmlcov/|venv/)
repos:
- repo: https://github.com/psf/black
rev: 21.11b1
rev: 22.3.0
hooks:
- id: black
language_version: python3

@ -11,10 +11,16 @@ Python Monero module
.. |coveralls| image:: https://coveralls.io/repos/github/monero-ecosystem/monero-python/badge.svg
.. _coveralls: https://coveralls.io/github/monero-ecosystem/monero-python
.. warning:: **URGENT SECURITY UPDATE**
The version 1.0.2 contains an urgent security update in the output recognition code. If you're
using the module for scanning transactions and identifying outputs using the secret view key,
UPDATE THE SOFTWARE IMMEDIATELY.
Otherwise you're safe. Standard wallet operations like receiving payments, spending, address
generation etc. are NOT AFFECTED.
A comprehensive Python module for handling Monero cryptocurrency.
* release 1.0.1
* release 1.0.2
* open source: https://github.com/monero-ecosystem/monero-python
* works with Monero 0.17.x and `the latest source`_ (at least we try to keep up)
* Python 2.x and 3.x compatible
@ -37,7 +43,7 @@ Released under the BSD 3-Clause License. See `LICENSE.txt`_.
Copyright (c) 2017-2018 Michał Sałaban <michal@salaban.info> and Contributors:
`lalanza808`_, `cryptochangements34`_, `atward`_, `rooterkyberian`_, `brucexiu`_,
`lialsoftlab`_, `moneroexamples`_, `massanchik`_, `MrClottom`_, `jeffro256`_,
`sometato`_.
`sometato`_, `kayabaNerve`_, `j-berman`_.
Copyright (c) 2016 The MoneroPy Developers (``monero/base58.py`` taken from `MoneroPy`_)
@ -58,6 +64,8 @@ Copyright (c) 2011 thomasv@gitorious (``monero/seed.py`` based on `Electrum`_)
.. _`MrClottom`: https://github.com/MrClottom
.. _`jeffro256`: https://github.com/jeffro256
.. _`sometato`: https://github.com/sometato
.. _`kayabaNerve`: https://github.com/kayabaNerve
.. _`j-berman`: https://github.com/j-berman
Want to help?
-------------

@ -4,7 +4,7 @@ Authors
* Michał Sałaban <michal@salaban.info>
* MoneroPy Developers (``monero/base58.py`` taken from `MoneroPy`_)
* thomasv@gitorious (``monero/seed.py`` based on `Electrum`_)
* and other Contributors: `lalanza808`_, `cryptochangements34`_, `atward`_, `rooterkyberian`_, `brucexiu`_, `lialsoftlab`_, `moneroexamples`_, `massanchik`_, `MrClottom`_, `jeffro256`_, `sometato`_.
* and other Contributors: `lalanza808`_, `cryptochangements34`_, `atward`_, `rooterkyberian`_, `brucexiu`_, `lialsoftlab`_, `moneroexamples`_, `massanchik`_, `MrClottom`_, `jeffro256`_, `sometato`_, `kayabaNerve`_, `j-berman`_.
.. _`LICENSE.txt`: LICENSE.txt
@ -22,6 +22,8 @@ Authors
.. _`MrClottom`: https://github.com/MrClottom
.. _`jeffro256`: https://github.com/jeffro256
.. _`sometato`: https://github.com/sometato
.. _`kayabaNerve`: https://github.com/kayabaNerve
.. _`j-berman`: https://github.com/j-berman
Acknowledgements
----------------

@ -27,7 +27,7 @@ sys.path.insert(0, os.path.abspath("../.."))
# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = '1.0.1'
# needs_sphinx = '1.0.2'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
@ -56,9 +56,9 @@ author = "Michal Salaban"
# built documents.
#
# The short X.Y version.
version = "1.0.1"
version = "1.0.2"
# The full version, including alpha/beta/rc tags.
release = "1.0.1"
release = "1.0.2"
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.

@ -3,6 +3,13 @@
Python module for Monero
========================
.. warning:: **URGENT SECURITY UPDATE**
The version 1.0.2 contains an urgent security update in the output recognition code. If you're
using the module for scanning transactions and identifying outputs using the secret view key,
UPDATE THE SOFTWARE IMMEDIATELY.
Otherwise you're safe. Standard wallet operations like receiving payments, spending, address
generation etc. are NOT AFFECTED.
Welcome to the documentation for the ``monero`` Python module.
The aim of this project is to offer a set of tools for interacting with Monero

@ -1,3 +1,3 @@
from . import address, account, const, daemon, wallet, numbers, wordlists, seed
__version__ = "1.0.1"
__version__ = "1.0.2"

@ -7,6 +7,15 @@ scalar_add = nacl.bindings.crypto_core_ed25519_scalar_add
scalarmult_B = nacl.bindings.crypto_scalarmult_ed25519_base_noclamp
scalarmult = nacl.bindings.crypto_scalarmult_ed25519_noclamp
# https://github.com/monero-project/monero/blob/9f814edbd78c70c70b814ca934c1ddef58768262/src/ringct/rctTypes.h#L615
H = binascii.unhexlify(
"8b655970153799af2aeadc9ff1add0ea6c7251d54154cfa92c173a0dd39c1f94"
)
def scalarmult_H(v):
return scalarmult(v, H)
def scalar_reduce(v):
return nacl.bindings.crypto_core_ed25519_scalar_reduce(v + (64 - len(v)) * b"\0")

@ -140,7 +140,7 @@ class Transaction(object):
already generated.
"""
def _scan_pubkeys(svk, psk, stealth_address, amount, encamount):
def _scan_pubkeys(svk, psk, stealth_address, amount, encamount, commitment):
for keyidx, tx_key in enumerate(self.pubkeys):
# precompute
svk_2 = ed25519.scalar_add(svk, svk)
@ -174,14 +174,22 @@ class Transaction(object):
dec_amount = bytearray(
a ^ b for a, b in zip(*map(bytearray, (encamount, xormask)))
)
int_amount = struct.unpack("<Q", dec_amount)[0]
amount = from_atomic(int_amount)
return Payment(
amount=amount,
timestamp=self.timestamp,
transaction=self,
local_address=addr,
)
# verify that the commitment == yG + bH
# https://web.getmonero.org/library/Zero-to-Monero-2-0-0.pdf#section.5.3
y = ed25519.scalar_reduce(keccak_256(b"commitment_mask" + Hs).digest())
yG = ed25519.scalarmult_B(y)
b = ed25519.scalar_reduce(bytes(dec_amount))
bH = ed25519.scalarmult_H(b)
amount = 0
if commitment == ed25519.edwards_add(yG, bH):
int_amount = struct.unpack("<Q", dec_amount)[0]
amount = from_atomic(int_amount)
return Payment(
amount=amount,
timestamp=self.timestamp,
transaction=self,
local_address=addr,
)
if not self.json:
raise exceptions.TransactionWithoutJSON(
@ -203,10 +211,14 @@ class Transaction(object):
for idx, vout in enumerate(self.json["vout"]):
stealth_address = binascii.unhexlify(vout["target"]["key"])
encamount = None
commitment = None
if self.version == 2 and not self.is_coinbase:
encamount = binascii.unhexlify(
self.json["rct_signatures"]["ecdhInfo"][idx]["amount"]
)
commitment = binascii.unhexlify(
self.json["rct_signatures"]["outPk"][idx]
)
payment = None
amount = (
from_atomic(vout["amount"])
@ -217,7 +229,7 @@ class Transaction(object):
for addridx, addr in enumerate(addresses):
psk = binascii.unhexlify(addr.spend_key())
payment = _scan_pubkeys(
svk, psk, stealth_address, amount, encamount
svk, psk, stealth_address, amount, encamount, commitment
)
if payment:
break

@ -1,4 +1,4 @@
pycryptodomex~=3.10
pycryptodomex~=3.14
pynacl~=1.4
pysocks~=1.7
requests

@ -1,8 +1,8 @@
black==21.11b1
coverage~=5.3
coveralls~=2.1
black~=22.3
coverage~=6.3
coveralls~=3.3
pip>=9
pytest-cov~=2.10
pytest-cov~=3.0
pytest-runner~=5.2
pytest~=6.1
responses~=0.12
pytest~=7.1
responses~=0.20

@ -0,0 +1,30 @@
{
"credits": 0,
"status": "OK",
"top_hash": "",
"txs": [
{
"as_hex": "",
"as_json": "{\n \"version\": 2, \n \"unlock_time\": 0, \n \"vin\": [ {\n \"key\": {\n \"amount\": 0, \n \"key_offsets\": [ 4325102, 464564, 19546, 7828, 15534, 180, 1645, 763, 454, 2046, 9\n ], \n \"k_image\": \"235fa321338a6317a6064fc13b9917c5b9e36dc929b0d3f01d19a6ff9a1d9169\"\n }\n }\n ], \n \"vout\": [ {\n \"amount\": 0, \n \"target\": {\n \"key\": \"4cd1c255c3247d2c2324fb580dd66f1158acc0ba352a4bddf9bb5d724f2b9d4a\"\n }\n }, {\n \"amount\": 0, \n \"target\": {\n \"key\": \"72a976004da61eabbe7ef1f074ac1ad960347f18b63e79c0b4075c70c6faa71a\"\n }\n }\n ], \n \"extra\": [ 1, 147, 181, 21, 141, 147, 122, 16, 161, 230, 64, 52, 218, 173, 173, 125, 69, 35, 14, 168, 251, 151, 140, 33, 64, 2, 68, 15, 75, 31, 24, 59, 150, 2, 9, 1, 56, 181, 21, 158, 240, 73, 6, 247\n ], \n \"rct_signatures\": {\n \"type\": 5, \n \"txnFee\": 44760000, \n \"ecdhInfo\": [ {\n \"amount\": \"bb400d3177c30ab5\"\n }, {\n \"amount\": \"c284adb69f34912c\"\n }], \n \"outPk\": [ \"2b63045a7fc922e73eb74cf179ca1640f36ba97ce8f27137dc30ca8e407d99c1\", \"a25db81bcfaf13950d9a353c6c2a55f45e103fa91d3dadad19cb1087f425fa96\"]\n }\n}",
"block_height": 1079424,
"block_timestamp": 1650936396,
"double_spend_seen": false,
"in_pool": false,
"output_indices": [
4837766,
4837767
],
"prunable_as_hex": "",
"prunable_hash": "ab173d3c08a7251cfd9ca58c67345368828f6f5f1d92972b79d080489956c154",
"pruned_as_hex": "02000102000beefd8702b4ad1cda9801943dae79b401ed0cfb05c603fe0f09235fa321338a6317a6064fc13b9917c5b9e36dc929b0d3f01d19a6ff9a1d91690200024cd1c255c3247d2c2324fb580dd66f1158acc0ba352a4bddf9bb5d724f2b9d4a000272a976004da61eabbe7ef1f074ac1ad960347f18b63e79c0b4075c70c6faa71a2c0193b5158d937a10a1e64034daadad7d45230ea8fb978c214002440f4b1f183b9602090138b5159ef04906f705c0f7ab15bb400d3177c30ab5c284adb69f34912c2b63045a7fc922e73eb74cf179ca1640f36ba97ce8f27137dc30ca8e407d99c1a25db81bcfaf13950d9a353c6c2a55f45e103fa91d3dadad19cb1087f425fa96",
"tx_hash": "f7e60d07c8e201b779871e3817edf8388e6ea775922def5758aef231d3ced36a"
}
],
"txs_as_hex": [
""
],
"txs_as_json": [
"{\n \"version\": 2, \n \"unlock_time\": 0, \n \"vin\": [ {\n \"key\": {\n \"amount\": 0, \n \"key_offsets\": [ 4325102, 464564, 19546, 7828, 15534, 180, 1645, 763, 454, 2046, 9\n ], \n \"k_image\": \"235fa321338a6317a6064fc13b9917c5b9e36dc929b0d3f01d19a6ff9a1d9169\"\n }\n }\n ], \n \"vout\": [ {\n \"amount\": 0, \n \"target\": {\n \"key\": \"4cd1c255c3247d2c2324fb580dd66f1158acc0ba352a4bddf9bb5d724f2b9d4a\"\n }\n }, {\n \"amount\": 0, \n \"target\": {\n \"key\": \"72a976004da61eabbe7ef1f074ac1ad960347f18b63e79c0b4075c70c6faa71a\"\n }\n }\n ], \n \"extra\": [ 1, 147, 181, 21, 141, 147, 122, 16, 161, 230, 64, 52, 218, 173, 173, 125, 69, 35, 14, 168, 251, 151, 140, 33, 64, 2, 68, 15, 75, 31, 24, 59, 150, 2, 9, 1, 56, 181, 21, 158, 240, 73, 6, 247\n ], \n \"rct_signatures\": {\n \"type\": 5, \n \"txnFee\": 44760000, \n \"ecdhInfo\": [ {\n \"amount\": \"bb400d3177c30ab5\"\n }, {\n \"amount\": \"c284adb69f34912c\"\n }], \n \"outPk\": [ \"2b63045a7fc922e73eb74cf179ca1640f36ba97ce8f27137dc30ca8e407d99c1\", \"a25db81bcfaf13950d9a353c6c2a55f45e103fa91d3dadad19cb1087f425fa96\"]\n }\n}"
],
"untrusted": false
}

@ -0,0 +1,18 @@
{
"id": 0,
"jsonrpc": "2.0",
"result": {
"subaddress_accounts": [
{
"account_index": 0,
"balance": 11709717332048,
"base_address": "54LUsTyVL2haFdvkUVngGCiacaRYkjrUvfhvnF6JS2fXNL6twQUQf7PEPtf9MvRYXvhVmtzcV2MUefinDjjwVcH56xm3AHx",
"label": "Primary account",
"tag": "",
"unlocked_balance": 11709717332048
}
],
"total_balance": 11709717332048,
"total_unlocked_balance": 11709717332048
}
}

@ -0,0 +1,7 @@
{
"id": 0,
"jsonrpc": "2.0",
"result": {
"key": "a759f8631116a607e0d905c09c633e320825d3a05e2b5fc54ab5f812f01a1d04"
}
}

@ -0,0 +1,69 @@
{
"id": 0,
"jsonrpc": "2.0",
"result": {
"address": "54LUsTyVL2haFdvkUVngGCiacaRYkjrUvfhvnF6JS2fXNL6twQUQf7PEPtf9MvRYXvhVmtzcV2MUefinDjjwVcH56xm3AHx",
"addresses": [
{
"address": "54LUsTyVL2haFdvkUVngGCiacaRYkjrUvfhvnF6JS2fXNL6twQUQf7PEPtf9MvRYXvhVmtzcV2MUefinDjjwVcH56xm3AHx",
"address_index": 0,
"label": "Primary account",
"used": true
},
{
"address": "74fu2Uiveqg8XwxtLK4kdMPkCZNuW8gGC7nWgB8kJF1rACfbGvPKirrSaKFnxtUJePfnGTPRQ1Tp3jR2PKAavqQ7RNrsJbb",
"address_index": 1,
"label": "(Untitled address)",
"used": true
},
{
"address": "72KSFPEUK5MDvo716tgRrndsRgB3UtWczAXVBjqDZCvRitvUKKA8saNH9LCD1ExCM5VAKuZJTtnH495vEupxRn7EEYbUrGV",
"address_index": 2,
"label": "(Untitled address)",
"used": true
},
{
"address": "7As2Hf3RwGWSCJAPFFHXDyLg5qywN8MiqcmpWPiM3Mc7bmuoA1V78HWEf3GctXtveHSH35hk6NVGK7TAQoyXpy3ATvEYgPz",
"address_index": 3,
"label": "(Untitled address)",
"used": true
},
{
"address": "771dkwjPR1UDTMM7NVbJ6LDX2pQdBaHqDZKSzViPTDaxVjG7idfF9uP2i8xftcV1JfZYESDzvFvAUJ1ym89uPy7VQ9Nd9BA",
"address_index": 4,
"label": "(Untitled address)",
"used": true
},
{
"address": "798wHkYNUqc5UWYdeYiFmrYeXV7Rd23MqasV3YWAYLbeieYb3ogLEkB9TugZkP72qMMtnhxAuyr62P9GLk3Ai5EMS6mCTdu",
"address_index": 5,
"label": "(Untitled address)",
"used": true
},
{
"address": "7AVgqHzSLu227tv2HGvPAYcbVqTzbbNsAC99QpPZwZzudGsEypD4ZjrQQcansdaQGDLtUbdEhqHfeNjgEWPFAUoVGq1dnbE",
"address_index": 6,
"label": "(Untitled address)",
"used": true
},
{
"address": "77xBMPG3k5qEmQmreBbeqJYwcx9kkEz2y2abCFvRRrjKZVr2LVois3kGRM4kzXUqmj7PtTkiUza6rXnNZ5HM17pd2AbsVEA",
"address_index": 7,
"label": "(Untitled address)",
"used": true
},
{
"address": "72barfe7Sp9JZkyLCYLn3wfGhysUUQJqgJPp7DtjStjFdFUXR376ypzYKyxgMcXNE3AStjFmaSKAq6pv78jKPsbTTLq3uNb",
"address_index": 8,
"label": "(Untitled address)",
"used": true
},
{
"address": "77a1kZkpr9uZMD2kcunkE67JiNN6dZhXAUa6ACFtP8j4MqTipM1QW5FSLkeEJZ5jzaMYNauPcavyPMF2VCVr8i5XEFizNkv",
"address_index": 9,
"label": "(Untitled address)",
"used": false
}
]
}
}

@ -0,0 +1,30 @@
{
"credits": 0,
"status": "OK",
"top_hash": "",
"txs": [
{
"as_hex": "",
"as_json": "{\n \"version\": 2, \n \"unlock_time\": 0, \n \"vin\": [ {\n \"key\": {\n \"amount\": 0, \n \"key_offsets\": [ 4675357, 101625, 27510, 10864, 17256, 2990, 745, 369, 17, 654, 290\n ], \n \"k_image\": \"8d07ba16fd1bcc8eeb2fa485eb293baafe4a06f6096f948fedb6679606c7ea9c\"\n }\n }\n ], \n \"vout\": [ {\n \"amount\": 0, \n \"target\": {\n \"key\": \"5c09c39a189d1ceb7bceb1929a4fc676642d4277fdd3abaec2a3f7c0368e8077\"\n }\n }, {\n \"amount\": 0, \n \"target\": {\n \"key\": \"1a8b5aa09c1ccfb310ad913a6b577a7e723a53619fb4fd1d9b5e831fc1694be0\"\n }\n }\n ], \n \"extra\": [ 1, 65, 88, 164, 63, 169, 150, 146, 177, 47, 124, 96, 195, 68, 227, 158, 193, 234, 47, 182, 8, 160, 78, 94, 188, 2, 231, 225, 89, 49, 186, 237, 123, 2, 9, 1, 130, 171, 128, 151, 207, 6, 115, 252\n ], \n \"rct_signatures\": {\n \"type\": 5, \n \"txnFee\": 44790000, \n \"ecdhInfo\": [ {\n \"amount\": \"1ad451cc41a9baf7\"\n }, {\n \"amount\": \"0a6ded7a1104d184\"\n }], \n \"outPk\": [ \"9338cbbdc552ac770797da8af3a589b02e9ad5928d439875760d89dfae1de4ba\", \"05e5685aa757e6420ef889107c7d4c0fc64c698f8bbaa7192ba7164c88ce8b46\"]\n }\n}",
"block_height": 1079424,
"block_timestamp": 1650936396,
"double_spend_seen": false,
"in_pool": false,
"output_indices": [
4837768,
4837769
],
"prunable_as_hex": "",
"prunable_hash": "7c4eccf0c4f947280645e3aa18f250b90d8466bdedc9371bcca780321fa1e00b",
"pruned_as_hex": "02000102000b9dae9d02f99906f6d601f054e88601ae17e905f102118e05a2028d07ba16fd1bcc8eeb2fa485eb293baafe4a06f6096f948fedb6679606c7ea9c0200025c09c39a189d1ceb7bceb1929a4fc676642d4277fdd3abaec2a3f7c0368e807700021a8b5aa09c1ccfb310ad913a6b577a7e723a53619fb4fd1d9b5e831fc1694be02c014158a43fa99692b12f7c60c344e39ec1ea2fb608a04e5ebc02e7e15931baed7b02090182ab8097cf0673fc05f0e1ad151ad451cc41a9baf70a6ded7a1104d1849338cbbdc552ac770797da8af3a589b02e9ad5928d439875760d89dfae1de4ba05e5685aa757e6420ef889107c7d4c0fc64c698f8bbaa7192ba7164c88ce8b46",
"tx_hash": "54731f9263e92c9e249d8eb677f7c8f1c7edb9812092479f026062139842e0e0"
}
],
"txs_as_hex": [
""
],
"txs_as_json": [
"{\n \"version\": 2, \n \"unlock_time\": 0, \n \"vin\": [ {\n \"key\": {\n \"amount\": 0, \n \"key_offsets\": [ 4675357, 101625, 27510, 10864, 17256, 2990, 745, 369, 17, 654, 290\n ], \n \"k_image\": \"8d07ba16fd1bcc8eeb2fa485eb293baafe4a06f6096f948fedb6679606c7ea9c\"\n }\n }\n ], \n \"vout\": [ {\n \"amount\": 0, \n \"target\": {\n \"key\": \"5c09c39a189d1ceb7bceb1929a4fc676642d4277fdd3abaec2a3f7c0368e8077\"\n }\n }, {\n \"amount\": 0, \n \"target\": {\n \"key\": \"1a8b5aa09c1ccfb310ad913a6b577a7e723a53619fb4fd1d9b5e831fc1694be0\"\n }\n }\n ], \n \"extra\": [ 1, 65, 88, 164, 63, 169, 150, 146, 177, 47, 124, 96, 195, 68, 227, 158, 193, 234, 47, 182, 8, 160, 78, 94, 188, 2, 231, 225, 89, 49, 186, 237, 123, 2, 9, 1, 130, 171, 128, 151, 207, 6, 115, 252\n ], \n \"rct_signatures\": {\n \"type\": 5, \n \"txnFee\": 44790000, \n \"ecdhInfo\": [ {\n \"amount\": \"1ad451cc41a9baf7\"\n }, {\n \"amount\": \"0a6ded7a1104d184\"\n }], \n \"outPk\": [ \"9338cbbdc552ac770797da8af3a589b02e9ad5928d439875760d89dfae1de4ba\", \"05e5685aa757e6420ef889107c7d4c0fc64c698f8bbaa7192ba7164c88ce8b46\"]\n }\n}"
],
"untrusted": false
}

@ -0,0 +1 @@
test_v2_single_output_with_fake_amount_to_master-wallet-00-get_accounts.json

@ -0,0 +1 @@
test_v2_single_output_with_fake_amount_to_master-wallet-01-query_key.json

@ -0,0 +1 @@
test_v2_single_output_with_fake_amount_to_master-wallet-02-addresses-account-0.json

@ -157,6 +157,108 @@ class OutputTestCase(JSONTestCase):
"to [76Qt2x]",
)
@responses.activate
def test_v2_single_output_with_fake_amount_to_master(self):
"""
Tests a transaction with real amount of 5.0 XMR and faked amount of ~2^24 XMR
through a forged value of "ecdhInfo" field.
"""
responses.add(
responses.POST,
self.wallet_jsonrpc_url,
json=self._read(
"test_v2_single_output_with_fake_amount_to_master-wallet-00-get_accounts.json"
),
status=200,
)
responses.add(
responses.POST,
self.wallet_jsonrpc_url,
json=self._read(
"test_v2_single_output_with_fake_amount_to_master-wallet-01-query_key.json"
),
status=200,
)
responses.add(
responses.POST,
self.wallet_jsonrpc_url,
json=self._read(
"test_v2_single_output_with_fake_amount_to_master-wallet-02-addresses-account-0.json"
),
status=200,
)
responses.add(
responses.POST,
self.daemon_transactions_url,
json=self._read(
"test_v2_single_output_with_fake_amount_to_master-daemon-00-get_transactions.json"
),
status=200,
)
wallet = Wallet(JSONRPCWallet(host="127.0.0.1", port=38083))
daemon = Daemon(JSONRPCDaemon(host="127.0.0.1", port=38081))
tx = daemon.transactions(
"f7e60d07c8e201b779871e3817edf8388e6ea775922def5758aef231d3ced36a"
)[0]
outs = tx.outputs(wallet=wallet)
self.assertEqual(len(outs), 2)
for n, out in enumerate(outs):
self.assertIsNone(
out.payment,
f"Output {n} contains a payment with incorrect ecdhInfo",
)
@responses.activate
def test_v2_single_output_with_fake_amount_to_subaddr(self):
"""
Tests a transaction with real amount of 3.0 XMR and faked amount of ~2^24 XMR
through a forged value of "ecdhInfo" field.
"""
responses.add(
responses.POST,
self.wallet_jsonrpc_url,
json=self._read(
"test_v2_single_output_with_fake_amount_to_subaddr-wallet-00-get_accounts.json"
),
status=200,
)
responses.add(
responses.POST,
self.wallet_jsonrpc_url,
json=self._read(
"test_v2_single_output_with_fake_amount_to_subaddr-wallet-01-query_key.json"
),
status=200,
)
responses.add(
responses.POST,
self.wallet_jsonrpc_url,
json=self._read(
"test_v2_single_output_with_fake_amount_to_subaddr-wallet-02-addresses-account-0.json"
),
status=200,
)
responses.add(
responses.POST,
self.daemon_transactions_url,
json=self._read(
"test_v2_single_output_with_fake_amount_to_subaddr-daemon-00-get_transactions.json"
),
status=200,
)
wallet = Wallet(JSONRPCWallet(host="127.0.0.1", port=38083))
daemon = Daemon(JSONRPCDaemon(host="127.0.0.1", port=38081))
tx = daemon.transactions(
"54731f9263e92c9e249d8eb677f7c8f1c7edb9812092479f026062139842e0e0"
)[0]
outs = tx.outputs(wallet=wallet)
self.assertEqual(len(outs), 2)
for n, out in enumerate(outs):
self.assertIsNone(
out.payment,
f"Output {n} contains a payment with incorrect ecdhInfo",
)
def test_coinbase_no_own_output(self):
txdata = self._read("test_coinbase_no_own_output-26dcb5.json")
tx = Transaction(

Loading…
Cancel
Save