Commit 877a4f52 authored by Vincent Texier's avatar Vincent Texier

Merge branch '0543' into 'master'

Release 0.54.3

See merge request !64
parents e5132867 958e2b3f
Pipeline #5703 passed with stages
in 2 minutes and 20 seconds
## v0.54.3 (29th May 2019)
- Upload again to PyPi as previous release haven’t been uploaded thanks to the tag
- Transaction: fix `time` type
## v0.54.2 (27th May 2019)
- fix Transaction document generation
- lock transaction document generation with a test
## v0.54.1 (9th May 2019)
- `Transaction`: add __eq__() and __hash__() methods
- Transaction Unlock parameters: add __eq__() and __hash__() methods
- Transaction: add 'time' variable for read and write but not for doc generation
- output conditions: add __eq__() and __hash__() methods
- test transaction equality at all levels
---
- Thanks @Moul, @vtexier
## v0.54.0 (5th May 2019)
### Code/tests
......@@ -16,6 +35,8 @@
- setup.py: add classifiers: Python versions, Intended Audience
- Add CHANGELOG.md from v0.53.1
---
- Thanks @Moul, @vtexier
## v0.53.1 (18 April 2019)
......
......@@ -72,9 +72,9 @@ author = 'caner & inso & vit'
# built documents.
#
# The short X.Y version.
version = '0.54.0'
version = '0.54.3'
# The full version, including alpha/beta/rc tags.
release = '0.54.0'
release = '0.54.3'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
......
......@@ -18,7 +18,7 @@
__author__ = 'Caner Candan & inso & vit'
__version__ = '0.54.0'
__version__ = '0.54.3'
__nonsense__ = 'duniter'
from . import api, documents, key
......@@ -230,6 +230,19 @@ class SIGParameter:
"""
self.index = index
def __eq__(self, other: Any) -> bool:
"""
Check SIGParameter instances equality
"""
if not isinstance(other, SIGParameter):
return NotImplemented
return self.index == other.index
def __hash__(self) -> int:
return hash((self.index))
@classmethod
def from_parameter(cls: Type[SIGParameterType], parameter: str) -> Optional[SIGParameterType]:
"""
......@@ -272,6 +285,19 @@ class XHXParameter:
"""
self.integer = integer
def __eq__(self, other: Any) -> bool:
"""
Check XHXParameter instances equality
"""
if not isinstance(other, XHXParameter):
return NotImplemented
return self.integer == other.integer
def __hash__(self) -> int:
return hash((self.integer))
@classmethod
def from_parameter(cls: Type[XHXParameterType], parameter: str) -> Optional[XHXParameterType]:
"""
......@@ -348,6 +374,24 @@ class Unlock:
self.index = index
self.parameters = parameters
def __eq__(self, other: Any) -> bool:
"""
Check Unlock instances equality
"""
if not isinstance(other, Unlock):
return NotImplemented
params_equals = True
for spar, opar in zip(self.parameters, other.parameters):
if spar != opar:
params_equals = False
return self.index == other.index and params_equals
def __hash__(self) -> int:
return hash((self.index, self.parameters))
@classmethod
def from_inline(cls: Type[UnlockType], inline: str) -> UnlockType:
"""
......@@ -448,7 +492,7 @@ class Transaction(Document):
def __init__(self, version: int, currency: str, blockstamp: Optional[BlockUID], locktime: int, issuers: List[str],
inputs: List[InputSource], unlocks: List[Unlock], outputs: List[OutputSource],
comment: str, signatures: List[str]) -> None:
comment: str, signatures: List[str], time: Optional[int] = None) -> None:
"""
Init Transaction instance
......@@ -461,6 +505,7 @@ class Transaction(Document):
:param unlocks: List of Unlock instances
:param outputs: List of OutputSource instances
:param comment: Comment field
:param time: time when the transaction enters the blockchain
:param signatures: List of signatures
"""
super().__init__(version, currency, signatures)
......@@ -471,6 +516,31 @@ class Transaction(Document):
self.unlocks = unlocks
self.outputs = outputs
self.comment = comment
self.time = time
def __eq__(self, other: Any) -> bool:
"""
Check Transaction instances equality
"""
if not isinstance(other, Transaction):
return NotImplemented
return self.version == other.version and \
self.currency == other.currency and \
self.signatures == other.signatures and \
self.blockstamp == other.blockstamp and \
self.locktime == other.locktime and \
self.issuers == other.issuers and \
self.inputs == other.inputs and \
self.unlocks == other.unlocks and \
self.outputs == other.outputs and \
self.comment == other.comment and \
self.time == other.time
def __hash__(self) -> int:
return hash((self.version, self.currency, self.signatures, self.blockstamp, self.locktime, self.issuers, self.inputs, self.unlocks, self.outputs, self.comment, self.time))
@classmethod
def from_bma_history(cls: Type[TransactionType], currency: str, tx_data: Dict) -> TransactionType:
......@@ -501,7 +571,7 @@ Outputs:
{multiline_outputs}
Comment: {comment}
{multiline_signatures}
""".format(**tx_data))
""".format(**tx_data), tx_data["time"])
@classmethod
def from_compact(cls: Type[TransactionType], currency: str, compact: str) -> TransactionType:
......@@ -575,11 +645,12 @@ Comment: {comment}
return cls(version, currency, blockstamp, locktime, issuers, inputs, unlocks, outputs, comment, signatures)
@classmethod
def from_signed_raw(cls: Type[TransactionType], raw: str) -> TransactionType:
def from_signed_raw(cls: Type[TransactionType], raw: str, time: int = 0) -> TransactionType:
"""
Return a Transaction instance from a raw string format
:param raw: Raw string format
:param time: time when the transaction enters the blockchain
:return:
"""
......@@ -645,7 +716,7 @@ Comment: {comment}
n += 1
return cls(version, currency, blockstamp, locktime, issuers, inputs, unlocks, outputs,
comment, signatures)
comment, signatures, time)
def raw(self) -> str:
"""
......@@ -732,7 +803,7 @@ class SimpleTransaction(Transaction):
def __init__(self, version: int, currency: str, blockstamp: BlockUID, locktime: int, issuer: str,
single_input: InputSource, unlocks: List[Unlock], outputs: List[OutputSource], comment: str,
signature: str) -> None:
signature: str, time: int) -> None:
"""
Init instance
......@@ -745,10 +816,11 @@ class SimpleTransaction(Transaction):
:param unlocks: List of Unlock instances
:param outputs: List of OutputSource instances
:param comment: Comment field
:param time: time when the transaction enters the blockchain
:param signature: Signature
"""
super().__init__(version, currency, blockstamp, locktime, [issuer], [single_input], unlocks,
outputs, comment, [signature])
outputs, comment, [signature], time)
@staticmethod
def is_simple(tx: Transaction) -> bool:
......
......@@ -48,6 +48,19 @@ class SIG:
def __str__(self) -> str:
return self.value
def __eq__(self, other: Any) -> bool:
"""
Check SIG instances equality
"""
if not isinstance(other, SIG):
return NotImplemented
return self.value == other.value and \
self.pubkey == other.pubkey
def __hash__(self) -> int:
return hash((self.value, self.pubkey))
@classmethod
def token(cls: Type[SIGType], pubkey: str) -> SIGType:
"""
......@@ -94,6 +107,19 @@ class CSV:
def __str__(self) -> str:
return self.value
def __eq__(self, other: Any) -> bool:
"""
Check CSV instances equality
"""
if not isinstance(other, CSV):
return NotImplemented
return self.value == other.value and \
self.time == other.time
def __hash__(self) -> int:
return hash((self.value, self.time))
@classmethod
def token(cls: Type[CSVType], time: int) -> CSVType:
"""
......@@ -139,6 +165,19 @@ class CLTV:
def __str__(self) -> str:
return self.value
def __eq__(self, other: Any) -> bool:
"""
Check CLTV instances equality
"""
if not isinstance(other, CLTV):
return NotImplemented
return self.value == other.value and \
self.timestamp == other.timestamp
def __hash__(self) -> int:
return hash((self.value, self.timestamp))
@classmethod
def token(cls: Type[CLTVType], timestamp: int) -> CLTVType:
"""
......@@ -184,6 +223,19 @@ class XHX:
def __str__(self) -> str:
return self.value
def __eq__(self, other: Any) -> bool:
"""
Check XHX instances equality
"""
if not isinstance(other, XHX):
return NotImplemented
return self.value == other.value and \
self.sha_hash == other.sha_hash
def __hash__(self) -> int:
return hash((self.value, self.sha_hash))
@classmethod
def token(cls: Type[XHXType], sha_hash: str) -> XHXType:
"""
......@@ -262,6 +314,21 @@ class Condition:
self.right = ''
self.op = ''
def __eq__(self, other: Any) -> bool:
"""
Check Condition instances equality
"""
if not isinstance(other, Condition):
return NotImplemented
return self.value == other.value and \
self.left == other.left and \
self.right == other.right and \
self.op == other.op
def __hash__(self) -> int:
return hash((self.value, self.left, self.right, self.op))
def __str__(self) -> str:
return self.value
......
......@@ -25,7 +25,7 @@ class SecretKey(libnacl.public.SecretKey):
:param salt: Salt credential
:param password: Password credential
:param scrypt_params: Optional ScriptParams instance
:param scrypt_params: Optional ScryptParams instance
"""
if scrypt_params is None:
scrypt_params = ScryptParams()
......
......@@ -6,7 +6,8 @@ Created on 12 déc. 2014
import unittest
import pypeg2
from duniterpy.grammars import output
from duniterpy.documents.transaction import Transaction, reduce_base, SimpleTransaction, InputSource, OutputSource
from duniterpy.documents import BlockUID
from duniterpy.documents.transaction import Transaction, reduce_base, SimpleTransaction, InputSource, OutputSource, Unlock, SIGParameter
compact_change = """TX:10:1:1:1:1:1:0
13410-000041DF0CCA173F09B5FBA48F619D4BC934F12ADF1D0B798639EB2149C4A8CC
......@@ -104,6 +105,9 @@ Comment: -----@@@----- (why not this comment?)
2XiBDpuUdu6zCPWGzHXXy8c4ATSscfFQG9DjmqMZUxDZVt1Dp4m2N5oHYVUfoPdrU9SLk4qxi65RNrfCVnvQtQJk
"""
input_source_str = "30:0:T:6991C993631BED4733972ED7538E41CCC33660F554E3C51963E2A0AC4D6453D3:2"
output_source_str = "460:0:SIG(8kXygUHh1vLjmcRzXVM86t38EL8dfFJgfBeHmkaWLamu)"
class TestTransaction(unittest.TestCase):
def test_fromcompact(self):
......@@ -291,18 +295,59 @@ class TestTransaction(unittest.TestCase):
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])
def test_transaction_equality(self):
t1 = Transaction.from_signed_raw(tx_raw)
t2 = Transaction.from_signed_raw(tx_raw)
self.assertTrue(t1 == t2)
t2.signatures = ["NSTN"]
self.assertFalse(t1 == t2)
t2 = Transaction.from_signed_raw(tx_raw)
t2.issuers = ["NSTRNRST"]
self.assertFalse(t1 == t2)
t2 = Transaction.from_signed_raw(tx_raw)
t2.time = 123
self.assertFalse(t1 == t2)
t2 = Transaction.from_signed_raw(tx_raw)
t2.inputs = InputSource.from_inline(input_source_str)
self.assertFalse(t1 == t2)
t2 = Transaction.from_signed_raw(tx_raw)
t2.outputs = OutputSource.from_inline(output_source_str)
self.assertFalse(t1 == t2)
def test_transaction_document_generation(self):
transaction = Transaction(
version=10,
currency="gtest",
blockstamp=BlockUID(8979, "000041DF0CCA173F09B5FBA48F619D4BC934F12ADF1D0B798639EB2149C4A8CC"),
locktime=0,
issuers=list("8kXygUHh1vLjmcRzXVM86t38EL8dfFJgfBeHmkaWLamu"),
inputs=[InputSource.from_inline(input_source_str)],
unlocks=[Unlock(index=0, parameters=[SIGParameter(0)])],
outputs=[OutputSource.from_inline(output_source_str)],
comment='',
signatures=[]
)
self.assertTrue(transaction.time == None)
self.assertTrue(transaction.currency == "gtest")
self.assertTrue(transaction.inputs[0].amount == 30)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment