diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 32a1b8935d1cdf520518b51913e347322680ca40..22a0fd66f56e3359fd1f45ff55e57d752fa269ce 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -37,8 +37,21 @@ push_to_github: - eval "$(pyenv init -)" - pyenv shell $PYENV_PYTHON_VERSION +.changes: &changes + except: + changes: + - CHANGELOG.md + - ci/* + - config + - docs + - LICENSE* + - Makefile + - README* + - release.sh + build: &build <<: *pyenv + <<: *changes stage: build script: - pip install -r requirements.txt @@ -47,6 +60,7 @@ build: &build test: <<: *pyenv + <<: *changes stage: test script: - pip install coveralls @@ -55,6 +69,7 @@ test: mypy: <<: *pyenv + <<: *changes stage: test script: - pip install -r requirements_dev.txt diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000000000000000000000000000000000..aba3f0b6893b5ea53b9298879920db507dea29ba --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,27 @@ +## v0.54.0 (XX April 2019) + +### Code/tests +- Fix OutputSource and InputSource from_inline() regex matching +- Transaction document: tests and code: drop versions 2 and 3 management +- Block document: code: drop vensions 2 and 3 management +- Block document: Upgrade blocks to v11 and TX to v10 +- Add OutputSource.inline_condition() method + +### Other +- CI: Do not trigger build, tests, type check on modification of non-relevant files +- Makefile: use python3 module to run tests and type check +- Add coveralls as dev dependency +- setup.py: add classifiers: Python versions, Intended Audience +- Add CHANGELOG.md from v0.53.1 + +- Thanks @Moul, @vtexier + +## v0.53.1 (18 April 2019) + +- Implement equality `__eq__()` and `__hash__()` methods for InputSource and OutputSource classes + +Thanks @Moul, @vtexier + +## v0.53.0 (30 March 2019) + +- To be completed… diff --git a/Makefile b/Makefile index 4d1db9708ec0d41af620f3cdf5e2e9b3bf5bae36..1c169e390cde0fc9118291a97a542fa33bee9638 100644 --- a/Makefile +++ b/Makefile @@ -6,8 +6,8 @@ docs: # run tests tests: - python -m unittest ${test_filter} + python3 -m unittest ${TESTS_FILTER} # check static typing check: - mypy duniterpy --ignore-missing-imports + python3 -m mypy duniterpy --ignore-missing-imports diff --git a/README.rst b/README.rst index 9e8b412e3d1d1fb428b7143a45220e9139c1e2bb..c7455629c76d62d8010b8f32ebf31466e333c138 100644 --- a/README.rst +++ b/README.rst @@ -69,9 +69,9 @@ Development make tests -* Run only some unit tests with:: +* Run only some unit tests by passing a special ENV variable:: - make tests test_filter=tests.documents.test_block.TestBlock.test_fromraw + make tests TESTS_FILTER=tests.documents.test_block.TestBlock.test_fromraw Documentation ------------- diff --git a/duniterpy/documents/block.py b/duniterpy/documents/block.py index 9ec967daff271db06619f6366dc3dde4fe71512c..ad2afe035edaa5018b2e638ad1456edf0abd74d3 100644 --- a/duniterpy/documents/block.py +++ b/duniterpy/documents/block.py @@ -75,8 +75,6 @@ The class Block handles Block documents. re_previoushash = re.compile("PreviousHash: ({block_hash_regex})\n".format(block_hash_regex=BLOCK_HASH_REGEX)) re_previousissuer = re.compile("PreviousIssuer: ({pubkey_regex})\n".format(pubkey_regex=PUBKEY_REGEX)) re_parameters = re.compile("Parameters: ([0-9]+\\.[0-9]+):([0-9]+):([0-9]+):([0-9]+):([0-9]+):([0-9]+):\ -([0-9]+):([0-9]+):([0-9]+\\.[0-9]+):([0-9]+):([0-9]+):([0-9]+):([0-9]+):([0-9]+):([0-9]+):([0-9]+\\.[0-9]+)\n") - re_parameters_v10 = re.compile("Parameters: ([0-9]+\\.[0-9]+):([0-9]+):([0-9]+):([0-9]+):([0-9]+):([0-9]+):\ ([0-9]+):([0-9]+):([0-9]+):([0-9]+):([0-9]+\\.[0-9]+):([0-9]+):([0-9]+):([0-9]+):([0-9]+):([0-9]+):([0-9]+\\.[0-9]+):\ ([0-9]+):([0-9]+):([0-9]+)\n") re_memberscount = re.compile("MembersCount: ([0-9]+)\n") @@ -252,24 +250,18 @@ The class Block handles Block documents. ud = int(Block.parse_field("UD", lines[n])) n += 1 - if version >= 3 or ud: - unit_base = int(Block.parse_field("UnitBase", lines[n])) - n += 1 + unit_base = int(Block.parse_field("UnitBase", lines[n])) + n += 1 issuer = Block.parse_field("Issuer", lines[n]) n += 1 - if version >= 3: - issuers_frame = Block.parse_field("IssuersFrame", lines[n]) - n += 1 - issuers_frame_var = Block.parse_field("IssuersFrameVar", lines[n]) - n += 1 - different_issuers_count = Block.parse_field("DifferentIssuersCount", lines[n]) - n += 1 - else: - issuers_frame = None - issuers_frame_var = None - different_issuers_count = None + issuers_frame = Block.parse_field("IssuersFrame", lines[n]) + n += 1 + issuers_frame_var = Block.parse_field("IssuersFrameVar", lines[n]) + n += 1 + different_issuers_count = Block.parse_field("DifferentIssuersCount", lines[n]) + n += 1 prev_hash = None prev_issuer = None @@ -283,16 +275,10 @@ The class Block handles Block documents. parameters = None if number == 0: try: - if version >= 10: - params_match = Block.re_parameters_v10.match(lines[n]) - if params_match is None: - raise MalformedDocumentError("Parameters") - parameters = params_match.groups() - else: - params_match = Block.re_parameters.match(lines[n]) - if params_match is None: - raise MalformedDocumentError("Parameters") - parameters = params_match.groups() + params_match = Block.re_parameters.match(lines[n]) + if params_match is None: + raise MalformedDocumentError("Parameters") + parameters = params_match.groups() n += 1 except AttributeError: raise MalformedDocumentError("Parameters") @@ -374,12 +360,7 @@ The class Block handles Block documents. unlocks_num = int(header_data.group(4)) outputs_num = int(header_data.group(5)) has_comment = int(header_data.group(6)) - if version > 2: - if tx_version <= 2: - raise MalformedDocumentError("TX document is using wrong version") - sup_lines = 2 - else: - sup_lines = 1 + sup_lines = 2 tx_max = n + sup_lines + issuers_num * 2 + inputs_num + unlocks_num + outputs_num + has_comment for i in range(n, tx_max): tx_lines += lines[n] @@ -419,13 +400,11 @@ MedianTime: {mediantime} if self.ud: doc += "UniversalDividend: {0}\n".format(self.ud) - if self.version >= 3 or self.ud: - doc += "UnitBase: {0}\n".format(self.unit_base) + doc += "UnitBase: {0}\n".format(self.unit_base) doc += "Issuer: {0}\n".format(self.issuer) - if self.version >= 3: - doc += """IssuersFrame: {0} + doc += """IssuersFrame: {0} IssuersFrameVar: {1} DifferentIssuersCount: {2} """.format(self.issuers_frame, self.issuers_frame_var, self.different_issuers_count) diff --git a/duniterpy/documents/block_uid.py b/duniterpy/documents/block_uid.py index 65a2816f6b1bf8c85eea3d974217f5f65c19a60d..025510476047fd5c01017a7935eaac07cfb663be 100644 --- a/duniterpy/documents/block_uid.py +++ b/duniterpy/documents/block_uid.py @@ -56,22 +56,22 @@ class BlockUID: def __lt__(self, other: object) -> bool: if not isinstance(other, BlockUID): - return False + return NotImplemented return self.number < other.number def __gt__(self, other: object) -> bool: if not isinstance(other, BlockUID): - return False + return NotImplemented return self.number > other.number def __le__(self, other: object) -> bool: if not isinstance(other, BlockUID): - return False + return NotImplemented return self.number <= other.number def __ge__(self, other: object) -> bool: if not isinstance(other, BlockUID): - return False + return NotImplemented return self.number >= other.number def __hash__(self) -> int: diff --git a/duniterpy/documents/document.py b/duniterpy/documents/document.py index 55677bd8c222a08c9c92e66efa407ea245cbdbc0..fa4f62122855096dda633b6a3b43e25f6b6485da 100644 --- a/duniterpy/documents/document.py +++ b/duniterpy/documents/document.py @@ -44,8 +44,6 @@ class Document: :param currency: Name of the currency :param signatures: List of signatures """ - if version < 2: - raise MalformedDocumentError("Version 1 documents are not handled by duniterpy>0.2") self.version = version self.currency = currency if signatures: diff --git a/duniterpy/documents/transaction.py b/duniterpy/documents/transaction.py index fa3f19af2882f9d7b5da095585363a0c11a4d102..8f8ea6dada456208457896fb5aca3e3bc4a15c57 100644 --- a/duniterpy/documents/transaction.py +++ b/duniterpy/documents/transaction.py @@ -50,13 +50,8 @@ class InputSource: """ re_inline = re.compile( - "(?:(?:(D):({pubkey_regex}):({block_id_regex}))|(?:(T):({transaction_hash_regex}):([0-9]+)))\n" - .format(pubkey_regex=PUBKEY_REGEX, - block_id_regex=BLOCK_ID_REGEX, - transaction_hash_regex=TRANSACTION_HASH_REGEX)) - re_inline_v3 = re.compile( - "([0-9]+):([0-9]+):(?:(?:(D):({pubkey_regex}):({block_id_regex}))|(?:(T):({transaction_hash_regex}):\ -([0-9]+)))\n" + "([0-9]+):([0-9]):(?:(?:(D):({pubkey_regex}):({block_id_regex}))|(?:(T):({transaction_hash_regex}):\ +([0-9]+)))" .format(pubkey_regex=PUBKEY_REGEX, block_id_regex=BLOCK_ID_REGEX, transaction_hash_regex=TRANSACTION_HASH_REGEX)) @@ -94,28 +89,19 @@ class InputSource: return hash((self.amount, self.base, self.source, self.origin_id, self.index)) @classmethod - def from_inline(cls: Type[InputSourceType], tx_version: int, inline: str) -> InputSourceType: + def from_inline(cls: Type[InputSourceType], inline: str) -> InputSourceType: """ Return Transaction instance from inline string format - :param tx_version: Version number of the document :param inline: Inline string format :return: """ - if tx_version == 2: - data = InputSource.re_inline.match(inline) - if data is None: - raise MalformedDocumentError("Inline input") - source_offset = 0 - amount = 0 - base = 0 - else: - data = InputSource.re_inline_v3.match(inline) - if data is None: - raise MalformedDocumentError("Inline input") - source_offset = 2 - amount = int(data.group(1)) - base = int(data.group(2)) + data = InputSource.re_inline.match(inline) + if data is None: + raise MalformedDocumentError("Inline input") + source_offset = 2 + amount = int(data.group(1)) + base = int(data.group(2)) if data.group(1 + source_offset): source = data.group(1 + source_offset) origin_id = data.group(2 + source_offset) @@ -127,19 +113,13 @@ class InputSource: return cls(amount, base, source, origin_id, index) - def inline(self, tx_version: int) -> str: + def inline(self) -> str: """ Return an inline string format of the document - :param tx_version: Version number of the document :return: """ - if tx_version == 2: - return "{0}:{1}:{2}".format(self.source, - self.origin_id, - self.index) - else: - return "{0}:{1}:{2}:{3}:{4}".format(self.amount, + return "{0}:{1}:{2}:{3}:{4}".format(self.amount, self.base, self.source, self.origin_id, @@ -154,7 +134,7 @@ class OutputSource: """ A Transaction OUTPUT """ - re_inline = re.compile("([0-9]+):([0-9]+):(.*)\n") + re_inline = re.compile("([0-9]+):([0-9]):(.*)") def __init__(self, amount: int, base: int, condition: str) -> None: """ @@ -200,13 +180,21 @@ class OutputSource: def inline(self) -> str: """ - Return an inline string format of the document + Return an inline string format of the output source :return: """ return "{0}:{1}:{2}".format(self.amount, self.base, pypeg2.compose(self.condition, output.Condition)) + def inline_condition(self) -> str: + """ + Return an inline string format of the output source’s condition + + :return: + """ + return pypeg2.compose(self.condition, output.Condition) + @staticmethod def condition_from_text(text) -> Condition: """ @@ -557,10 +545,8 @@ Comment: {comment} locktime = int(header_data.group(7)) n += 1 - blockstamp = None # type: Optional[BlockUID] - if version >= 3: - blockstamp = BlockUID.from_str(Transaction.parse_field("CompactBlockstamp", lines[n])) - n += 1 + blockstamp = BlockUID.from_str(Transaction.parse_field("CompactBlockstamp", lines[n])) + n += 1 issuers = [] inputs = [] @@ -573,7 +559,7 @@ Comment: {comment} n += 1 for i in range(0, inputs_num): - input_source = InputSource.from_inline(version, lines[n]) + input_source = InputSource.from_inline(lines[n]) inputs.append(input_source) n += 1 @@ -651,7 +637,7 @@ Comment: {comment} if Transaction.re_inputs.match(lines[n]): n += 1 while Transaction.re_unlocks.match(lines[n]) is None: - input_source = InputSource.from_inline(version, lines[n]) + input_source = InputSource.from_inline(lines[n]) inputs.append(input_source) n += 1 @@ -704,7 +690,7 @@ Currency: {1} doc += "Inputs:\n" for i in self.inputs: - doc += "{0}\n".format(i.inline(self.version)) + doc += "{0}\n".format(i.inline()) doc += "Unlocks:\n" for u in self.unlocks: @@ -747,7 +733,7 @@ COMMENT for pubkey in self.issuers: doc += "{0}\n".format(pubkey) for i in self.inputs: - doc += "{0}\n".format(i.inline(self.version)) + doc += "{0}\n".format(i.inline()) for u in self.unlocks: doc += "{0}\n".format(u.inline()) for o in self.outputs: diff --git a/requirements_dev.txt b/requirements_dev.txt index 5816b58ffe5061bef5e60cef8f520692e43a12ca..e70f7780458caa75b832fd0b6325c44ef9177712 100644 --- a/requirements_dev.txt +++ b/requirements_dev.txt @@ -1,3 +1,4 @@ +coveralls mypy sphinx sphinx_rtd_theme diff --git a/setup.py b/setup.py index 775b88415547d05f3f5e2b676932f51fcbfeb258..ce1b7ea516f1a7813c67860552f94a06f0148387 100644 --- a/setup.py +++ b/setup.py @@ -63,13 +63,16 @@ setup( test_suite="tests", classifiers=[ - "Programming Language :: Python", "Development Status :: 5 - Production/Stable", "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", "Natural Language :: English", "Operating System :: OS Independent", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.5", "Topic :: Software Development :: Libraries", + "Intended Audience :: Developers", ], install_requires=install_requires, dependency_links=dependency_links diff --git a/tests/documents/test_block.py b/tests/documents/test_block.py index 4472edc35252c8a2fe59bd0013d070affba43295..3e3562d49cc2ccbef9bdc3c5548a79f9b6bb99d4 100644 --- a/tests/documents/test_block.py +++ b/tests/documents/test_block.py @@ -8,14 +8,18 @@ import unittest from duniterpy.documents.block import Block from duniterpy.documents.block_uid import BlockUID, block_uid -raw_block = """Version: 2 +raw_block = """Version: 11 Type: Block Currency: zeta_brouzouf Number: 15 PoWMin: 4 Time: 1418083330 MedianTime: 1418080208 +UnitBase: 0 Issuer: HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk +IssuersFrame: 1 +IssuersFrameVar: 0 +DifferentIssuersCount: 0 PreviousHash: 0000E73C340601ACA1AD5AAA5B5E56B03E178EF8 PreviousIssuer: HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk MembersCount: 4 @@ -32,14 +36,18 @@ Nonce: 45079 42yQm4hGTJYWkPg39hQAUgP6S6EQ4vTfXdJuxKEHL1ih6YHiDL2hcwrFgBHjXLRgxRhj2VNVqqc6b4JayKqTE14r """ -raw_block_with_tx = """Version: 2 +raw_block_with_tx = """Version: 11 Type: Block Currency: meta_brouzouf Number: 34436 PoWMin: 5 Time: 1443896211 MedianTime: 1443881811 +UnitBase: 0 Issuer: HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk +IssuersFrame: 1 +IssuersFrameVar: 0 +DifferentIssuersCount: 0 PreviousHash: 000002B06C990DEBD5C1D947289C2CF4F4396FB2 PreviousIssuer: HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk MembersCount: 19 @@ -54,26 +62,28 @@ Certifications: 5ocqzyDMMWf1V8bsoNhWb1iNwax1e9M7VTUN6navs8of:ATkjQPa4sn4LBF69jqEPzFtRdHYJs6MJQjvP8JdN7MtN:0:6TuxRcARnpo13l3cXtgPTkjJlv8DZOUvsAzmZJMbjHZbbZfDQ6MJpH9DIuH0eyG3WGc0EX/046mbMGBrKKg9DQ== ATkjQPa4sn4LBF69jqEPzFtRdHYJs6MJQjvP8JdN7MtN:2qwGeLWoPG7db72bKXPfJpAtj67FYDnPaJn2JB7tyXxJ:0:LusTbb7CgwrqqacDKjtldw60swwvDBH8wVUIJN4SWRb2pZPJSpDxgqaGyjC5P9i/DendfyQWc7cfzPDqSZmZAg== Transactions: -TX:2:1:3:3:1:0:0 +TX:10:1:3:3:1:0:0 +33363-000021C4B5BE2DA996F953DC09482F4FA2FA68774B1A38FAB03B2AAB4A08EBE0 HsLShAtzXTVxeUtQd7yi5Z5Zh4zNvbu8sTEZ53nfKcqY -T:6991C993631BED4733972ED7538E41CCC33660F554E3C51963E2A0AC4D6453D3:0 -T:3A09A20E9014110FD224889F13357BAB4EC78A72F95CA03394D8CCA2936A7435:10 -D:HsLShAtzXTVxeUtQd7yi5Z5Zh4zNvbu8sTEZ53nfKcqY:88 +5200:0:T:6991C993631BED4733972ED7538E41CCC33660F554E3C51963E2A0AC4D6453D3:0 +500:0:T:3A09A20E9014110FD224889F13357BAB4EC78A72F95CA03394D8CCA2936A7435:10 +20:0:D:HsLShAtzXTVxeUtQd7yi5Z5Zh4zNvbu8sTEZ53nfKcqY:88 0:SIG(0) 1:SIG(0) 2:SIG(0) 30:2:SIG(BYfWYFrsyjpvpFysgu19rGK3VHBkz4MqmQbNyEuVU64g) 42yQm4hGTJYWkPg39hQAUgP6S6EQ4vTfXdJuxKEHL1ih6YHiDL2hcwrFgBHjXLRgxRhj2VNVqqc6b4JayKqTE14r -TX:2:3:6:6:3:1:0 +TX:10:3:6:6:3:1:0 +33363-000021C4B5BE2DA996F953DC09482F4FA2FA68774B1A38FAB03B2AAB4A08EBE0 HsLShAtzXTVxeUtQd7yi5Z5Zh4zNvbu8sTEZ53nfKcqY CYYjHsNyg3HMRMpTHqCJAN9McjH5BwFLmDKGV3PmCuKp 9WYHTavL1pmhunFCzUwiiq4pXwvgGG5ysjZnjz9H8yB -T:6991C993631BED4733972ED7538E41CCC33660F554E3C51963E2A0AC4D6453D3:2 -T:3A09A20E9014110FD224889F13357BAB4EC78A72F95CA03394D8CCA2936A7435:8 -D:HsLShAtzXTVxeUtQd7yi5Z5Zh4zNvbu8sTEZ53nfKcqY:46 -T:A0D9B4CDC113ECE1145C5525873821398890AE842F4B318BD076095A23E70956:3 -T:67F2045B5318777CC52CD38B424F3E40DDA823FA0364625F124BABE0030E7B5B:5 -D:9WYHTavL1pmhunFCzUwiiq4pXwvgGG5ysjZnjz9H8yB:46 +78900:0:T:6991C993631BED4733972ED7538E41CCC33660F554E3C51963E2A0AC4D6453D3:2 +700:0:T:3A09A20E9014110FD224889F13357BAB4EC78A72F95CA03394D8CCA2936A7435:8 +8900:0:D:HsLShAtzXTVxeUtQd7yi5Z5Zh4zNvbu8sTEZ53nfKcqY:46 +780:0:T:A0D9B4CDC113ECE1145C5525873821398890AE842F4B318BD076095A23E70956:3 +780:0:T:67F2045B5318777CC52CD38B424F3E40DDA823FA0364625F124BABE0030E7B5B:5 +8900:0:D:9WYHTavL1pmhunFCzUwiiq4pXwvgGG5ysjZnjz9H8yB:46 0:SIG(0) 1:XHX(7665798292) 2:SIG(0) @@ -92,7 +102,7 @@ Nonce: 581 nY/MsFU2luiohLmSiOOimL1RIqbriOBgc22ua03Z2dhxtSJxKZeGNGDvl1jaXgmEBRnXU87yXbZ7ioOS/AAVCA== """ -raw_block_zero = """Version: 10 +raw_block_zero = """Version: 11 Type: Block Currency: zeta_brouzouf Number: 0 @@ -139,14 +149,18 @@ Nonce: 2125 42yQm4hGTJYWkPg39hQAUgP6S6EQ4vTfXdJuxKEHL1ih6YHiDL2hcwrFgBHjXLRgxRhj2VNVqqc6b4JayKqTE14r """ -raw_block_with_leavers = """Version: 2 +raw_block_with_leavers = """Version: 11 Type: Block Currency: meta_brouzouf Number: 34895 PoWMin: 4 Time: 1444434128 MedianTime: 1444426438 +UnitBase: 0 Issuer: HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk +IssuersFrame: 1 +IssuersFrameVar: 0 +DifferentIssuersCount: 0 PreviousHash: 0000E88115ADDF79344372C0212928501E21622B PreviousIssuer: HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk MembersCount: 21 @@ -164,7 +178,7 @@ Nonce: 9906 5LZCFSnm5FkFihPBTpmsPyILEdvu8MXfJOp6OR4d1s+/e2jVWg4J6YSDfO2KBBPgubASyr2QwQuiBlYD2918Bw== """ -raw_block_with_excluded = """Version: 3 +raw_block_with_excluded = """Version: 11 Type: Block Currency: test_net Number: 33365 @@ -189,7 +203,7 @@ Excluded: 2VAxjr8QoJtSzhE7APno4AkR2RAQNySpNNvDzMgPotSF Certifications: Transactions: -TX:3:1:4:4:12:1:0 +TX:10:1:4:4:12:1:0 33363-000021C4B5BE2DA996F953DC09482F4FA2FA68774B1A38FAB03B2AAB4A08EBE0 TENGx7WtzFsTXwnbrPEvb6odX2WnqYcnnrjiiLvp1mS 5:0:T:D25272F1D778B52798B7A51CF0CE21F7C5812F841374508F4367872D4A47F0F7:0 @@ -219,7 +233,7 @@ Nonce: 137387 GmgYhWrwCtsK7t2B/omPpxZ8EfJgv9UYzJIFo++Za+A0Mo70xRfZG7kywxbQTTxDk/V7r90P946N89vdVjv1Bg== """ -negative_issuers_frame_var = """Version: 3 +negative_issuers_frame_var = """Version: 11 Type: Block Currency: test_net Number: 34662 @@ -242,7 +256,7 @@ Revoked: Excluded: Certifications: Transactions: -TX:3:1:4:4:2:1:0 +TX:10:1:4:4:2:1:0 34660-00001EEB3FDCEB2F9F39F931ED8F6D419C4C64B4D3F7EA52C35FB6B07A085664 5ocqzyDMMWf1V8bsoNhWb1iNwax1e9M7VTUN6navs8of 765201:3:T:636150D38D565DA0B9717E93C2AD8D6270FA032BF963360ECFCDD55F44493F08:1 @@ -266,7 +280,7 @@ WnJvw204wccmSBQK9UE2rCFw0EG34zf+b58n2KTLwSIhTpgmGsnr5ohkSyYZYcLEKjisLXKNCmMl7D1Q class TestBlock(unittest.TestCase): def test_fromraw(self): block = Block.from_signed_raw(raw_block) - self.assertEqual(block.version, 2) + self.assertEqual(block.version, 11) self.assertEqual(block.currency, "zeta_brouzouf") self.assertEqual(block.noonce, 45079) self.assertEqual(block.number, 15) @@ -287,7 +301,7 @@ class TestBlock(unittest.TestCase): def test_from_signed_raw_block_zero(self): block = Block.from_signed_raw(raw_block_zero) - self.assertEqual(block.version, 10) + self.assertEqual(block.version, 11) self.assertEqual(block.currency, "zeta_brouzouf") self.assertEqual(block.noonce, 2125) self.assertEqual(block.number, 0) @@ -315,7 +329,7 @@ class TestBlock(unittest.TestCase): rendered_raw = block.signed_raw() from_rendered_raw = Block.from_signed_raw(rendered_raw) - self.assertEqual(from_rendered_raw.version, 2) + self.assertEqual(from_rendered_raw.version, 11) self.assertEqual(from_rendered_raw.currency, "zeta_brouzouf") self.assertEqual(from_rendered_raw.noonce, 45079) self.assertEqual(from_rendered_raw.number, 15) @@ -341,7 +355,7 @@ class TestBlock(unittest.TestCase): rendered_raw = block.signed_raw() from_rendered_raw = block.from_signed_raw(rendered_raw) - self.assertEqual(from_rendered_raw.version, 10) + self.assertEqual(from_rendered_raw.version, 11) self.assertEqual(from_rendered_raw.currency, "zeta_brouzouf") self.assertEqual(from_rendered_raw.noonce, 2125) self.assertEqual(from_rendered_raw.number, 0) @@ -365,7 +379,7 @@ class TestBlock(unittest.TestCase): rendered_raw = block.signed_raw() from_rendered_raw = block.from_signed_raw(rendered_raw) - self.assertEqual(from_rendered_raw.version, 2) + self.assertEqual(from_rendered_raw.version, 11) self.assertEqual(from_rendered_raw.currency, "meta_brouzouf") self.assertEqual(from_rendered_raw.noonce, 581) self.assertEqual(from_rendered_raw.number, 34436) @@ -389,7 +403,7 @@ class TestBlock(unittest.TestCase): block = Block.from_signed_raw(raw_block_with_leavers) rendered_raw = block.signed_raw() from_rendered_raw = block.from_signed_raw(rendered_raw) - self.assertEqual(from_rendered_raw.version, 2) + self.assertEqual(from_rendered_raw.version, 11) self.assertEqual(from_rendered_raw.currency, "meta_brouzouf") self.assertEqual(from_rendered_raw.noonce, 9906) self.assertEqual(from_rendered_raw.number, 34895) @@ -452,7 +466,7 @@ class TestBlock(unittest.TestCase): self.fail("Empty blockuid __nonzero__ comparison failed") def test_proof_of_work(self): - block = """Version: 5 + block = """Version: 11 Type: Block Currency: test_net Number: 60803 diff --git a/tests/documents/test_transaction.py b/tests/documents/test_transaction.py index 64e01f83feb9507a4afb7a37019a0a7db65f8dcd..415397522a0ff1099e03e5e1dd6f324517fb1bff 100644 --- a/tests/documents/test_transaction.py +++ b/tests/documents/test_transaction.py @@ -6,7 +6,7 @@ Created on 12 déc. 2014 import unittest import pypeg2 from duniterpy.grammars import output -from duniterpy.documents.transaction import Transaction, reduce_base, SimpleTransaction +from duniterpy.documents.transaction import Transaction, reduce_base, SimpleTransaction, InputSource, OutputSource compact_change = """TX:10:1:1:1:1:1:0 13410-000041DF0CCA173F09B5FBA48F619D4BC934F12ADF1D0B798639EB2149C4A8CC @@ -35,16 +35,17 @@ Comment: XHX for pubkey DCYELkvV1aAsxFv58SbfRerHy5giJwKA1i4ZKTTcVGZe GXGephqTSJfb+8xsG/UMKRW0y+edL4RoMHM+OlgFq1aYOuaQ3/CtBKVSA01n2mkI7zwepeIABSjS94iVH4vZDg== """ -tx_compact = """TX:2:3:6:6:3:1:0 +tx_compact = """TX:10:3:6:6:3:1:0 +13410-000041DF0CCA173F09B5FBA48F619D4BC934F12ADF1D0B798639EB2149C4A8CC HsLShAtzXTVxeUtQd7yi5Z5Zh4zNvbu8sTEZ53nfKcqY CYYjHsNyg3HMRMpTHqCJAN9McjH5BwFLmDKGV3PmCuKp 9WYHTavL1pmhunFCzUwiiq4pXwvgGG5ysjZnjz9H8yB -T:6991C993631BED4733972ED7538E41CCC33660F554E3C51963E2A0AC4D6453D3:2 -T:3A09A20E9014110FD224889F13357BAB4EC78A72F95CA03394D8CCA2936A7435:8 -D:HsLShAtzXTVxeUtQd7yi5Z5Zh4zNvbu8sTEZ53nfKcqY:46 -T:A0D9B4CDC113ECE1145C5525873821398890AE842F4B318BD076095A23E70956:3 -T:67F2045B5318777CC52CD38B424F3E40DDA823FA0364625F124BABE0030E7B5B:5 -D:9WYHTavL1pmhunFCzUwiiq4pXwvgGG5ysjZnjz9H8yB:46 +230:2:T:6991C993631BED4733972ED7538E41CCC33660F554E3C51963E2A0AC4D6453D3:2 +2230:2:T:3A09A20E9014110FD224889F13357BAB4EC78A72F95CA03394D8CCA2936A7435:8 +2430:2:D:HsLShAtzXTVxeUtQd7yi5Z5Zh4zNvbu8sTEZ53nfKcqY:46 +2310:2:T:A0D9B4CDC113ECE1145C5525873821398890AE842F4B318BD076095A23E70956:3 +30:2:T:67F2045B5318777CC52CD38B424F3E40DDA823FA0364625F124BABE0030E7B5B:5 +2330:2:D:9WYHTavL1pmhunFCzUwiiq4pXwvgGG5ysjZnjz9H8yB:46 0:SIG(0) 1:XHX(7665798292) 2:SIG(0) @@ -60,48 +61,17 @@ D:9WYHTavL1pmhunFCzUwiiq4pXwvgGG5ysjZnjz9H8yB:46 2XiBDpuUdu6zCPWGzHXXy8c4ATSscfFQG9DjmqMZUxDZVt1Dp4m2N5oHYVUfoPdrU9SLk4qxi65RNrfCVnvQtQJk """ -tx_compact_2 = """TX:2:1:1:1:2:0:0 +simple_tx_compact = """TX:10:1:1:1:2:0:0 +13410-000041DF0CCA173F09B5FBA48F619D4BC934F12ADF1D0B798639EB2149C4A8CC GNPdPNwSJAYw7ixkDeibo3YpdELgLmrZ2Q86HF4cyg92 -D:GNPdPNwSJAYw7ixkDeibo3YpdELgLmrZ2Q86HF4cyg92:471 +100:0:D:GNPdPNwSJAYw7ixkDeibo3YpdELgLmrZ2Q86HF4cyg92:471 0:SIG(0) 90:0:SIG(5zDvFjJB1PGDQNiExpfzL9c1tQGs6xPA8mf1phr3VoVi) 10:0:SIG(GNPdPNwSJAYw7ixkDeibo3YpdELgLmrZ2Q86HF4cyg92) XDQeEMcJDd+XVGaFIZc8d4kKRJgsPuWAPVNG5UKNk8mDZx2oE1kTP/hbxiFx6yDouBELCswuf/X6POK9ES7JCA== """ -tx_raw = """Version: 2 -Type: Transaction -Currency: beta_brousouf -Locktime: 0 -Issuers: -HsLShAtzXTVxeUtQd7yi5Z5Zh4zNvbu8sTEZ53nfKcqY -CYYjHsNyg3HMRMpTHqCJAN9McjH5BwFLmDKGV3PmCuKp -9WYHTavL1pmhunFCzUwiiq4pXwvgGG5ysjZnjz9H8yB -Inputs: -T:6991C993631BED4733972ED7538E41CCC33660F554E3C51963E2A0AC4D6453D3:2 -T:3A09A20E9014110FD224889F13357BAB4EC78A72F95CA03394D8CCA2936A7435:8 -D:HsLShAtzXTVxeUtQd7yi5Z5Zh4zNvbu8sTEZ53nfKcqY:46 -T:A0D9B4CDC113ECE1145C5525873821398890AE842F4B318BD076095A23E70956:3 -T:67F2045B5318777CC52CD38B424F3E40DDA823FA0364625F124BABE0030E7B5B:5 -D:9WYHTavL1pmhunFCzUwiiq4pXwvgGG5ysjZnjz9H8yB:46 -Unlocks: -0:SIG(0) -1:XHX(7665798292) -2:SIG(0) -3:SIG(0) SIG(2) -4:SIG(0) SIG(1) SIG(2) -5:SIG(2) -Outputs: -120:2:SIG(BYfWYFrsyjpvpFysgu19rGK3VHBkz4MqmQbNyEuVU64g) -146:2:SIG(DSz4rgncXCytsUMW2JU2yhLquZECD2XpEkpP9gG5HyAx) -49:2:(SIG(6DyGr5LFtFmbaJYRvcs9WmBsr4cbJbJ1EV9zBbqG7A6i) || XHX(8FAA0ED653CA4D2C1156D511F0D0036F5168ABA4DAC2929676D279C8A2A12E36)) -Comment: -----@@@----- (why not this comment?) -42yQm4hGTJYWkPg39hQAUgP6S6EQ4vTfXdJuxKEHL1ih6YHiDL2hcwrFgBHjXLRgxRhj2VNVqqc6b4JayKqTE14r -2D96KZwNUvVtcapQPq2mm7J9isFcDCfykwJpVEZwBc7tCgL4qPyu17BT5ePozAE9HS6Yvj51f62Mp4n9d9dkzJoX -2XiBDpuUdu6zCPWGzHXXy8c4ATSscfFQG9DjmqMZUxDZVt1Dp4m2N5oHYVUfoPdrU9SLk4qxi65RNrfCVnvQtQJk -""" - -tx_raw_v3 = """Version: 3 +tx_raw = """Version: 10 Type: Transaction Currency: beta_brousouf Blockstamp: 32-DB30D958EE5CB75186972286ED3F4686B8A1C2CD @@ -138,109 +108,8 @@ Comment: -----@@@----- (why not this comment?) class TestTransaction(unittest.TestCase): def test_fromcompact(self): tx = Transaction.from_compact("zeta_brousouf", tx_compact) - self.assertEqual(tx.version, 2) - self.assertEqual(tx.currency, "zeta_brousouf") - self.assertEqual(len(tx.issuers), 3) - self.assertEqual(len(tx.inputs), 6) - self.assertEqual(len(tx.unlocks), 6) - self.assertEqual(len(tx.outputs), 3) - - self.assertEqual(tx.issuers[0], "HsLShAtzXTVxeUtQd7yi5Z5Zh4zNvbu8sTEZ53nfKcqY") - self.assertEqual(tx.issuers[1], "CYYjHsNyg3HMRMpTHqCJAN9McjH5BwFLmDKGV3PmCuKp") - self.assertEqual(tx.issuers[2], "9WYHTavL1pmhunFCzUwiiq4pXwvgGG5ysjZnjz9H8yB") - - self.assertEqual(tx.inputs[0].source, 'T') - self.assertEqual(tx.inputs[0].origin_id, "6991C993631BED4733972ED7538E41CCC33660F554E3C51963E2A0AC4D6453D3") - self.assertEqual(tx.inputs[0].index, 2) - self.assertEqual(tx.inputs[1].source, 'T') - self.assertEqual(tx.inputs[1].origin_id, "3A09A20E9014110FD224889F13357BAB4EC78A72F95CA03394D8CCA2936A7435") - self.assertEqual(tx.inputs[1].index, 8) - self.assertEqual(tx.inputs[2].source, 'D') - self.assertEqual(tx.inputs[2].origin_id, "HsLShAtzXTVxeUtQd7yi5Z5Zh4zNvbu8sTEZ53nfKcqY") - self.assertEqual(tx.inputs[2].index, 46) - self.assertEqual(tx.inputs[3].source, 'T') - self.assertEqual(tx.inputs[3].origin_id, "A0D9B4CDC113ECE1145C5525873821398890AE842F4B318BD076095A23E70956") - self.assertEqual(tx.inputs[3].index, 3) - self.assertEqual(tx.inputs[4].source, 'T') - self.assertEqual(tx.inputs[4].origin_id, "67F2045B5318777CC52CD38B424F3E40DDA823FA0364625F124BABE0030E7B5B") - self.assertEqual(tx.inputs[4].index, 5) - self.assertEqual(tx.inputs[5].source, 'D') - self.assertEqual(tx.inputs[5].origin_id, "9WYHTavL1pmhunFCzUwiiq4pXwvgGG5ysjZnjz9H8yB") - self.assertEqual(tx.inputs[5].index, 46) - - self.assertEqual(tx.unlocks[0].index, 0) - self.assertEqual(str(tx.unlocks[0].parameters[0]), "SIG(0)") - self.assertEqual(tx.unlocks[1].index, 1) - self.assertEqual(str(tx.unlocks[1].parameters[0]), "XHX(7665798292)") - self.assertEqual(tx.unlocks[2].index, 2) - self.assertEqual(str(tx.unlocks[2].parameters[0]), "SIG(0)") - self.assertEqual(tx.unlocks[3].index, 3) - self.assertEqual(str(tx.unlocks[3].parameters[0]), "SIG(0)") - self.assertEqual(str(tx.unlocks[3].parameters[1]), "SIG(2)") - self.assertEqual(tx.unlocks[4].index, 4) - self.assertEqual(str(tx.unlocks[4].parameters[0]), "SIG(0)") - self.assertEqual(str(tx.unlocks[4].parameters[1]), "SIG(1)") - self.assertEqual(str(tx.unlocks[4].parameters[2]), "SIG(2)") - self.assertEqual(tx.unlocks[5].index, 5) - self.assertEqual(str(tx.unlocks[5].parameters[0]), "SIG(2)") - - self.assertEqual(tx.outputs[0].amount, 120) - self.assertEqual(tx.outputs[0].base, 2) - self.assertEqual(pypeg2.compose(tx.outputs[0].condition, output.Condition), - "SIG(BYfWYFrsyjpvpFysgu19rGK3VHBkz4MqmQbNyEuVU64g)") - self.assertEqual(tx.outputs[1].amount, 146) - self.assertEqual(tx.outputs[1].base, 2) - self.assertEqual(pypeg2.compose(tx.outputs[1].condition, output.Condition), - "SIG(DSz4rgncXCytsUMW2JU2yhLquZECD2XpEkpP9gG5HyAx)") - self.assertEqual(tx.outputs[2].amount, 49) - self.assertEqual(tx.outputs[2].base, 2) - self.assertEqual(pypeg2.compose(tx.outputs[2].condition, output.Condition), - "(SIG(6DyGr5LFtFmbaJYRvcs9WmBsr4cbJbJ1EV9zBbqG7A6i) || XHX(8FAA0ED653CA4D2C1156D511F0D0036F5168ABA4DAC2929676D279C8A2A12E36))") - - self.assertEqual(tx.comment, "-----@@@----- (why not this comment?)") - - self.assertEqual(tx.signatures[0], - "42yQm4hGTJYWkPg39hQAUgP6S6EQ4vTfXdJuxKEHL1ih6YHiDL2hcwrFgBHjXLRgxRhj2VNVqqc6b4JayKqTE14r") - self.assertEqual(tx.signatures[1], - "2D96KZwNUvVtcapQPq2mm7J9isFcDCfykwJpVEZwBc7tCgL4qPyu17BT5ePozAE9HS6Yvj51f62Mp4n9d9dkzJoX") - self.assertEqual(tx.signatures[2], - "2XiBDpuUdu6zCPWGzHXXy8c4ATSscfFQG9DjmqMZUxDZVt1Dp4m2N5oHYVUfoPdrU9SLk4qxi65RNrfCVnvQtQJk") - - def test_fromcompact2(self): - tx = Transaction.from_compact("zeta_brousouf", tx_compact_2) - self.assertEqual(tx.version, 2) + self.assertEqual(tx.version, 10) self.assertEqual(tx.currency, "zeta_brousouf") - self.assertEqual(len(tx.issuers), 1) - self.assertEqual(len(tx.inputs), 1) - self.assertEqual(len(tx.unlocks), 1) - self.assertEqual(len(tx.outputs), 2) - - self.assertEqual(tx.issuers[0], "GNPdPNwSJAYw7ixkDeibo3YpdELgLmrZ2Q86HF4cyg92") - - self.assertEqual(tx.inputs[0].source, 'D') - self.assertEqual(tx.inputs[0].origin_id, "GNPdPNwSJAYw7ixkDeibo3YpdELgLmrZ2Q86HF4cyg92") - self.assertEqual(tx.inputs[0].index, 471) - - self.assertEqual(tx.unlocks[0].index, 0) - self.assertEqual(str(tx.unlocks[0].parameters[0]), "SIG(0)") - - self.assertEqual(tx.outputs[0].amount, 90) - self.assertEqual(tx.outputs[0].base, 0) - self.assertEqual(pypeg2.compose(tx.outputs[0].condition, output.Condition), - "SIG(5zDvFjJB1PGDQNiExpfzL9c1tQGs6xPA8mf1phr3VoVi)") - self.assertEqual(type(tx.outputs[0].condition.left), output.SIG) - self.assertEqual(tx.outputs[1].amount, 10) - self.assertEqual(tx.outputs[1].base, 0) - self.assertEqual(pypeg2.compose(tx.outputs[1].condition, output.Condition), - "SIG(GNPdPNwSJAYw7ixkDeibo3YpdELgLmrZ2Q86HF4cyg92)") - self.assertEqual(type(tx.outputs[1].condition.left), output.SIG) - self.assertEqual(tx.signatures[0], - "XDQeEMcJDd+XVGaFIZc8d4kKRJgsPuWAPVNG5UKNk8mDZx2oE1kTP/hbxiFx6yDouBELCswuf/X6POK9ES7JCA==") - - def test_fromraw(self): - tx = Transaction.from_signed_raw(tx_raw) - self.assertEqual(tx.version, 2) - self.assertEqual(tx.currency, "beta_brousouf") self.assertEqual(len(tx.issuers), 3) self.assertEqual(len(tx.inputs), 6) self.assertEqual(len(tx.unlocks), 6) @@ -250,21 +119,33 @@ class TestTransaction(unittest.TestCase): self.assertEqual(tx.issuers[1], "CYYjHsNyg3HMRMpTHqCJAN9McjH5BwFLmDKGV3PmCuKp") self.assertEqual(tx.issuers[2], "9WYHTavL1pmhunFCzUwiiq4pXwvgGG5ysjZnjz9H8yB") + self.assertEqual(tx.inputs[0].amount, 230) + self.assertEqual(tx.inputs[0].base, 2) self.assertEqual(tx.inputs[0].source, 'T') self.assertEqual(tx.inputs[0].origin_id, "6991C993631BED4733972ED7538E41CCC33660F554E3C51963E2A0AC4D6453D3") self.assertEqual(tx.inputs[0].index, 2) + self.assertEqual(tx.inputs[1].amount, 2230) + self.assertEqual(tx.inputs[1].base, 2) self.assertEqual(tx.inputs[1].source, 'T') self.assertEqual(tx.inputs[1].origin_id, "3A09A20E9014110FD224889F13357BAB4EC78A72F95CA03394D8CCA2936A7435") self.assertEqual(tx.inputs[1].index, 8) + self.assertEqual(tx.inputs[2].amount, 2430) + self.assertEqual(tx.inputs[2].base, 2) self.assertEqual(tx.inputs[2].source, 'D') self.assertEqual(tx.inputs[2].origin_id, "HsLShAtzXTVxeUtQd7yi5Z5Zh4zNvbu8sTEZ53nfKcqY") self.assertEqual(tx.inputs[2].index, 46) + self.assertEqual(tx.inputs[3].amount, 2310) + self.assertEqual(tx.inputs[3].base, 2) self.assertEqual(tx.inputs[3].source, 'T') self.assertEqual(tx.inputs[3].origin_id, "A0D9B4CDC113ECE1145C5525873821398890AE842F4B318BD076095A23E70956") self.assertEqual(tx.inputs[3].index, 3) + self.assertEqual(tx.inputs[4].amount, 30) + self.assertEqual(tx.inputs[4].base, 2) self.assertEqual(tx.inputs[4].source, 'T') self.assertEqual(tx.inputs[4].origin_id, "67F2045B5318777CC52CD38B424F3E40DDA823FA0364625F124BABE0030E7B5B") self.assertEqual(tx.inputs[4].index, 5) + self.assertEqual(tx.inputs[5].amount, 2330) + self.assertEqual(tx.inputs[5].base, 2) self.assertEqual(tx.inputs[5].source, 'D') self.assertEqual(tx.inputs[5].origin_id, "9WYHTavL1pmhunFCzUwiiq4pXwvgGG5ysjZnjz9H8yB") self.assertEqual(tx.inputs[5].index, 46) @@ -312,80 +193,7 @@ class TestTransaction(unittest.TestCase): rendered_tx = tx.signed_raw() from_rendered_tx = Transaction.from_signed_raw(rendered_tx) - self.assertEqual(tx.version, 2) - self.assertEqual(tx.currency, "beta_brousouf") - self.assertEqual(len(tx.issuers), 3) - self.assertEqual(len(tx.inputs), 6) - self.assertEqual(len(tx.unlocks), 6) - self.assertEqual(len(tx.outputs), 3) - - self.assertEqual(tx.issuers[0], "HsLShAtzXTVxeUtQd7yi5Z5Zh4zNvbu8sTEZ53nfKcqY") - self.assertEqual(tx.issuers[1], "CYYjHsNyg3HMRMpTHqCJAN9McjH5BwFLmDKGV3PmCuKp") - self.assertEqual(tx.issuers[2], "9WYHTavL1pmhunFCzUwiiq4pXwvgGG5ysjZnjz9H8yB") - - self.assertEqual(tx.inputs[0].source, 'T') - self.assertEqual(tx.inputs[0].origin_id, "6991C993631BED4733972ED7538E41CCC33660F554E3C51963E2A0AC4D6453D3") - self.assertEqual(tx.inputs[0].index, 2) - self.assertEqual(tx.inputs[1].source, 'T') - self.assertEqual(tx.inputs[1].origin_id, "3A09A20E9014110FD224889F13357BAB4EC78A72F95CA03394D8CCA2936A7435") - self.assertEqual(tx.inputs[1].index, 8) - self.assertEqual(tx.inputs[2].source, 'D') - self.assertEqual(tx.inputs[2].origin_id, "HsLShAtzXTVxeUtQd7yi5Z5Zh4zNvbu8sTEZ53nfKcqY") - self.assertEqual(tx.inputs[2].index, 46) - self.assertEqual(tx.inputs[3].source, 'T') - self.assertEqual(tx.inputs[3].origin_id, "A0D9B4CDC113ECE1145C5525873821398890AE842F4B318BD076095A23E70956") - self.assertEqual(tx.inputs[3].index, 3) - self.assertEqual(tx.inputs[4].source, 'T') - self.assertEqual(tx.inputs[4].origin_id, "67F2045B5318777CC52CD38B424F3E40DDA823FA0364625F124BABE0030E7B5B") - self.assertEqual(tx.inputs[4].index, 5) - self.assertEqual(tx.inputs[5].source, 'D') - self.assertEqual(tx.inputs[5].origin_id, "9WYHTavL1pmhunFCzUwiiq4pXwvgGG5ysjZnjz9H8yB") - self.assertEqual(tx.inputs[5].index, 46) - - self.assertEqual(tx.unlocks[0].index, 0) - self.assertEqual(str(tx.unlocks[0].parameters[0]), "SIG(0)") - self.assertEqual(tx.unlocks[1].index, 1) - self.assertEqual(str(tx.unlocks[1].parameters[0]), "XHX(7665798292)") - self.assertEqual(tx.unlocks[2].index, 2) - self.assertEqual(str(tx.unlocks[2].parameters[0]), "SIG(0)") - self.assertEqual(tx.unlocks[3].index, 3) - self.assertEqual(str(tx.unlocks[3].parameters[0]), "SIG(0)") - self.assertEqual(str(tx.unlocks[3].parameters[1]), "SIG(2)") - self.assertEqual(tx.unlocks[4].index, 4) - self.assertEqual(str(tx.unlocks[4].parameters[0]), "SIG(0)") - self.assertEqual(str(tx.unlocks[4].parameters[1]), "SIG(1)") - self.assertEqual(str(tx.unlocks[4].parameters[2]), "SIG(2)") - self.assertEqual(tx.unlocks[5].index, 5) - self.assertEqual(str(tx.unlocks[5].parameters[0]), "SIG(2)") - - self.assertEqual(tx.outputs[0].amount, 120) - self.assertEqual(tx.outputs[0].base, 2) - self.assertEqual(pypeg2.compose(tx.outputs[0].condition, output.Condition), - "SIG(BYfWYFrsyjpvpFysgu19rGK3VHBkz4MqmQbNyEuVU64g)") - self.assertEqual(tx.outputs[1].amount, 146) - self.assertEqual(tx.outputs[1].base, 2) - self.assertEqual(pypeg2.compose(tx.outputs[1].condition, output.Condition), - "SIG(DSz4rgncXCytsUMW2JU2yhLquZECD2XpEkpP9gG5HyAx)") - self.assertEqual(tx.outputs[2].amount, 49) - self.assertEqual(tx.outputs[2].base, 2) - self.assertEqual(pypeg2.compose(tx.outputs[2].condition, output.Condition), - "(SIG(6DyGr5LFtFmbaJYRvcs9WmBsr4cbJbJ1EV9zBbqG7A6i) || XHX(8FAA0ED653CA4D2C1156D511F0D0036F5168ABA4DAC2929676D279C8A2A12E36))") - - self.assertEqual(tx.comment, "-----@@@----- (why not this comment?)") - - self.assertEqual(tx.signatures[0], - "42yQm4hGTJYWkPg39hQAUgP6S6EQ4vTfXdJuxKEHL1ih6YHiDL2hcwrFgBHjXLRgxRhj2VNVqqc6b4JayKqTE14r") - self.assertEqual(tx.signatures[1], - "2D96KZwNUvVtcapQPq2mm7J9isFcDCfykwJpVEZwBc7tCgL4qPyu17BT5ePozAE9HS6Yvj51f62Mp4n9d9dkzJoX") - self.assertEqual(tx.signatures[2], - "2XiBDpuUdu6zCPWGzHXXy8c4ATSscfFQG9DjmqMZUxDZVt1Dp4m2N5oHYVUfoPdrU9SLk4qxi65RNrfCVnvQtQJk") - - def test_fromraw_toraw_v3(self): - tx = Transaction.from_signed_raw(tx_raw_v3) - rendered_tx = tx.signed_raw() - from_rendered_tx = Transaction.from_signed_raw(rendered_tx) - - self.assertEqual(tx.version, 3) + self.assertEqual(tx.version, 10) self.assertEqual(tx.currency, "beta_brousouf") self.assertEqual(tx.blockstamp.number, 32) self.assertEqual(tx.blockstamp.sha_hash, "DB30D958EE5CB75186972286ED3F4686B8A1C2CD") @@ -475,8 +283,26 @@ class TestTransaction(unittest.TestCase): self.assertEqual(computed[1], 5) def test_is_simple(self): - tx = Transaction.from_compact("zeta_brousouf", tx_compact_2) + tx = Transaction.from_compact("zeta_brousouf", simple_tx_compact) self.assertTrue(SimpleTransaction.is_simple(tx)) tx = Transaction.from_compact("zeta_brousouf", tx_compact) self.assertFalse(SimpleTransaction.is_simple(tx)) + + + def test_inputsource_from_inline(self): + input_source_str = "30:0:T:6991C993631BED4733972ED7538E41CCC33660F554E3C51963E2A0AC4D6453D3:2" + i = InputSource.from_inline(input_source_str) + self.assertEqual(i.inline(), input_source_str) + + + def test_outputsource_from_inline(self): + output_source_str = "460:0:SIG(8kXygUHh1vLjmcRzXVM86t38EL8dfFJgfBeHmkaWLamu)" + o = OutputSource.from_inline(output_source_str) + self.assertEqual(o.inline(), output_source_str) + + + def test_outputsource_inline_condition(self): + output_source_str = "460:0:SIG(8kXygUHh1vLjmcRzXVM86t38EL8dfFJgfBeHmkaWLamu)" + o = OutputSource.from_inline(output_source_str) + self.assertEqual(o.inline_condition(), output_source_str.split(":")[2])