Commit 676b1099 authored by Vincent Texier's avatar Vincent Texier

Merge branch 'transaction' into 'dev'

Several transaction enhancements, other improvements

See merge request !56
parents 3a1e5d61 4db793ba
Pipeline #5330 passed with stages
in 43 seconds
......@@ -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
......
## 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…
......@@ -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
......@@ -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
-------------
......
......@@ -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)
......
......@@ -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:
......
......@@ -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:
......
......@@ -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:
......
coveralls
mypy
sphinx
sphinx_rtd_theme
......@@ -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
......
......@@ -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
......
......@@ -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)