Skip to content
This repository was archived by the owner on Jan 13, 2023. It is now read-only.

Commit 6e0b5c2

Browse files
authored
Merge pull request #286 from lzpap/trytestring_randomlength
Use class length for random TryteString generation
2 parents 41cc47a + cb8c9e2 commit 6e0b5c2

File tree

5 files changed

+113
-4
lines changed

5 files changed

+113
-4
lines changed

iota/crypto/types.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ class Seed(TryteString):
112112
- https://iota.stackexchange.com/q/249
113113
"""
114114

115+
LEN = 81
116+
"""
117+
Length of a Seed.
118+
"""
119+
115120
def __init__(self, trytes=None):
116121
# type: (Optional[TrytesCompatible]) -> None
117122
if trytes and len(trytes) > Hash.LEN:

iota/types.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,19 +68,28 @@ class TryteString(JsonSerializable):
6868
"""
6969

7070
@classmethod
71-
def random(cls, length):
72-
# type: (int) -> TryteString
71+
def random(cls, length=None):
72+
# type: (Optional[int]) -> TryteString
7373
"""
7474
Generates a random sequence of trytes.
7575
76-
:param int length:
76+
:param Optional[int] length:
7777
Number of trytes to generate.
7878
7979
:return:
8080
:py:class:`TryteString` object.
8181
"""
8282
alphabet = list(itervalues(AsciiTrytesCodec.alphabet))
8383
generator = SystemRandom()
84+
try:
85+
if length is None:
86+
length = cls.LEN
87+
88+
if length <= 0:
89+
raise TypeError("length parameter needs to be greater than zero")
90+
except AttributeError: # class has no LEN attribute
91+
if length is None:
92+
raise TypeError("{class_name} does not define a length property".format(class_name=cls.__name__))
8493

8594
# :py:meth:`SystemRandom.choices` wasn't added until Python 3.6;
8695
# for compatibility, we will continue to use ``choice`` in a

test/crypto/types_test.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,12 @@ def test_init_error_too_short(self):
7979
with self.assertRaises(ValueError):
8080
Digest(b'9' * (2 * Hash.LEN - 1))
8181

82+
def test_random(self):
83+
"""
84+
Generating a random Digest should fail.
85+
"""
86+
with self.assertRaises(TypeError):
87+
random_digest = Digest.random()
8288

8389
# noinspection SpellCheckingInspection
8490
class PrivateKeyTestCase(TestCase):
@@ -152,3 +158,10 @@ def test_get_digest_multiple_fragments(self):
152158
#
153159
# Each fragment is processed independently, which is critical for
154160
# multisig to work correctly.
161+
162+
def test_random(self):
163+
"""
164+
Generating a random PrivateKey should fail.
165+
"""
166+
with self.assertRaises(TypeError):
167+
random_digest = PrivateKey.random()

test/transaction/types_test.py

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66

77
from six import binary_type
88

9-
from iota import TransactionHash
9+
from iota import TransactionHash, BundleHash, Fragment, TransactionTrytes, \
10+
Nonce
1011

1112

1213
class TransactionHashTestCase(TestCase):
@@ -39,3 +40,42 @@ def test_init_error_too_long(self):
3940
b'JVMTDGDPDFYHMZPMWEKKANBQSLSDTIIHAYQUMZOK'
4041
b'HXXXGJHJDQPOMDOMNRDKYCZRUFZROZDADTHZC99999'
4142
)
43+
44+
def test_random(self):
45+
"""
46+
Creating a random TransactionHash object.
47+
"""
48+
random_tx_hash = TransactionHash.random()
49+
self.assertEqual(len(random_tx_hash), TransactionHash.LEN)
50+
51+
class BundleHashTestCase(TestCase):
52+
def test_random(self):
53+
"""
54+
Creating a random BundleHash object.
55+
"""
56+
random_bundle_hash = BundleHash.random()
57+
self.assertEqual(len(random_bundle_hash), BundleHash.LEN)
58+
59+
class FragmentTestCase(TestCase):
60+
def test_random(self):
61+
"""
62+
Creating a random Fragment object.
63+
"""
64+
random_fragment = Fragment.random()
65+
self.assertEqual(len(random_fragment), Fragment.LEN)
66+
67+
class TransactionTrytesTestCase(TestCase):
68+
def test_random(self):
69+
"""
70+
Creating a random TransactionTrytes object.
71+
"""
72+
random_tx_trytes = TransactionTrytes.random()
73+
self.assertEqual(len(random_tx_trytes), TransactionTrytes.LEN)
74+
75+
class NonceTestCase(TestCase):
76+
def test_random(self):
77+
"""
78+
Creating a random Nonce object.
79+
"""
80+
random_nonce = Nonce.random()
81+
self.assertEqual(len(random_nonce), Nonce.LEN)

test/types_test.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,20 @@ def test_random(self):
754754
# generated.
755755
self.assertEqual(len(trytes), Hash.LEN)
756756

757+
def test_random_no_length(self):
758+
"""
759+
Trying to create a random TryteString without specifying length.
760+
"""
761+
with self.assertRaises(TypeError):
762+
trytes = TryteString.random()
763+
764+
def test_random_wrong_length(self):
765+
"""
766+
Generating random Trytestring with negative length.
767+
"""
768+
with self.assertRaises(TypeError):
769+
trytes = TryteString.random(length=-5)
770+
757771
def test_from_bytes(self):
758772
"""
759773
Converting a sequence of bytes into a TryteString.
@@ -883,6 +897,14 @@ def test_from_trits_wrong_length_padded(self):
883897
b'RBTC',
884898
)
885899

900+
class HashTestCase(TestCase):
901+
def test_random(self):
902+
"""
903+
Generating a random Hash.
904+
"""
905+
rand = Hash.random()
906+
self.assertEqual(len(rand), Hash.LEN)
907+
886908

887909
# noinspection SpellCheckingInspection
888910
class AddressTestCase(TestCase):
@@ -1124,6 +1146,12 @@ def test_remove_checksum_second_time(self):
11241146
self.assertFalse(addy.is_checksum_valid())
11251147
self.assertTrue(len(addy) == Address.LEN)
11261148

1149+
def test_random(self):
1150+
"""
1151+
Creating a random Address object.
1152+
"""
1153+
addy = Address.random()
1154+
self.assertEqual(len(addy), Address.LEN)
11271155

11281156
# noinspection SpellCheckingInspection
11291157
class AddressChecksumTestCase(TestCase):
@@ -1149,6 +1177,13 @@ def test_init_error_too_long(self):
11491177
# If it's an address checksum, it must be 9 trytes exactly.
11501178
AddressChecksum(b'FOXM9MUBX9')
11511179

1180+
def test_random(self):
1181+
"""
1182+
Creating a random AddressChecksum object.
1183+
"""
1184+
checksum = AddressChecksum.random()
1185+
self.assertEqual(len(checksum), AddressChecksum.LEN)
1186+
11521187

11531188
# noinspection SpellCheckingInspection
11541189
class TagTestCase(TestCase):
@@ -1167,3 +1202,10 @@ def test_init_error_too_long(self):
11671202
with self.assertRaises(ValueError):
11681203
# 28 chars = no va.
11691204
Tag(b'COLOREDCOINS9999999999999999')
1205+
1206+
def test_random(self):
1207+
"""
1208+
Creating a random Tag object.
1209+
"""
1210+
tag = Tag.random()
1211+
self.assertEqual(len(tag), Tag.LEN)

0 commit comments

Comments
 (0)