Skip to content

Commit e27d101

Browse files
committed
New exception MalformedErrorDocument
1 parent b964c9d commit e27d101

File tree

10 files changed

+202
-229
lines changed

10 files changed

+202
-229
lines changed

_ucoinpy_test/documents/test_status.py

Lines changed: 0 additions & 38 deletions
This file was deleted.

ucoinpy/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
MANAGED_API=["BASIC_MERKLED_API"]
2222

2323
__author__ = 'Caner Candan & inso'
24-
__version__ = '0.14.2'
24+
__version__ = '0.14.3'
2525
__nonsense__ = 'uCoin'
2626

2727
from . import api, documents, key

ucoinpy/documents/__init__.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,5 @@
22
from .certification import SelfCertification, Certification
33
from .membership import Membership
44
from .peer import Endpoint, BMAEndpoint, UnknownEndpoint, Peer
5-
from .status import Status
65
from .transaction import SimpleTransaction, Transaction
7-
from .document import Document
6+
from .document import Document, MalformedDocumentError

ucoinpy/documents/block.py

Lines changed: 67 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from .document import Document
1+
from .document import Document, MalformedDocumentError
22
from .certification import SelfCertification, Certification
33
from .membership import Membership
44
from .transaction import Transaction
@@ -28,6 +28,8 @@ def from_str(cls, blockid):
2828
:param str blockid: The block id
2929
"""
3030
data = blockid.split("-")
31+
if len(data) != 2:
32+
raise MalformedDocumentError('BlockId')
3133
number = int(data[0])
3234
sha_hash = data[1]
3335
return cls(number, sha_hash)
@@ -107,6 +109,28 @@ class Block(Document):
107109
re_certifications = re.compile("Certifications:\n")
108110
re_transactions = re.compile("Transactions:\n")
109111

112+
fields_parsers = {**Document.fields_parsers, **{
113+
'Type': re_type,
114+
'Noonce': re_noonce,
115+
'Number': re_number,
116+
'PoWMin': re_powmin,
117+
'Time': re_time,
118+
'MedianTime': re_mediantime,
119+
'UD': re_universaldividend,
120+
'Issuer': re_issuer,
121+
'PreviousIssuer': re_previousissuer,
122+
'PreviousHash': re_previoushash,
123+
'Parameters': re_parameters,
124+
'MembersCount': re_memberscount,
125+
'Identities': re_identities,
126+
'Joiners': re_joiners,
127+
'Actives': re_actives,
128+
'Leavers': re_leavers,
129+
'Certifications': re_certifications,
130+
'Transactions': re_transactions
131+
}
132+
}
133+
110134
Empty_Hash = "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709"
111135

112136
def __init__(self, version, currency, noonce, number, powmin, time,
@@ -167,54 +191,54 @@ def from_signed_raw(cls, raw):
167191
lines = raw.splitlines(True)
168192
n = 0
169193

170-
version = int(Block.re_version.match(lines[n]).group(1))
171-
n = n + 1
194+
version = int(Block.parse_field("Version", lines[n]))
195+
n += 1
172196

173-
Block.re_type.match(lines[n]).group(1)
174-
n = n + 1
197+
Block.parse_field("Type", lines[n])
198+
n += 1
175199

176-
currency = Block.re_currency.match(lines[n]).group(1)
177-
n = n + 1
200+
currency = Block.parse_field("Currency", lines[n])
201+
n += 1
178202

179-
noonce = int(Block.re_noonce.match(lines[n]).group(1))
180-
n = n + 1
203+
noonce = int(Block.parse_field("Noonce", lines[n]))
204+
n += 1
181205

182-
number = int(Block.re_number.match(lines[n]).group(1))
183-
n = n + 1
206+
number = int(Block.parse_field("Number", lines[n]))
207+
n += 1
184208

185-
powmin = int(Block.re_powmin.match(lines[n]).group(1))
186-
n = n + 1
209+
powmin = int(Block.parse_field("PoWMin", lines[n]))
210+
n += 1
187211

188-
time = int(Block.re_time.match(lines[n]).group(1))
189-
n = n + 1
212+
time = int(Block.parse_field("Time", lines[n]))
213+
n += 1
190214

191-
mediantime = int(Block.re_mediantime.match(lines[n]).group(1))
192-
n = n + 1
215+
mediantime = int(Block.parse_field("MedianTime", lines[n]))
216+
n += 1
193217

194218
ud = Block.re_universaldividend.match(lines[n])
195219
if ud is not None:
196220
ud = int(ud.group(1))
197-
n = n + 1
221+
n += 1
198222

199-
issuer = Block.re_issuer.match(lines[n]).group(1)
200-
n = n + 1
223+
issuer = Block.parse_field("Issuer", lines[n])
224+
n += 1
201225

202226
prev_hash = None
203227
prev_issuer = None
204228
if number > 0:
205-
prev_hash = Block.re_previoushash.match(lines[n]).group(1)
206-
n = n + 1
229+
prev_hash = Block.parse_field("PreviousHash", lines[n])
230+
n += 1
207231

208-
prev_issuer = Block.re_previousissuer.match(lines[n]).group(1)
209-
n = n + 1
232+
prev_issuer = Block.parse_field("PreviousIssuer", lines[n])
233+
n += 1
210234

211235
parameters = None
212236
if number == 0:
213237
parameters = Block.re_parameters.match(lines[n]).groups()
214-
n = n + 1
238+
n += 1
215239

216-
members_count = int(Block.re_memberscount.match(lines[n]).group(1))
217-
n = n + 1
240+
members_count = int(Block.parse_field("MembersCount", lines[n]))
241+
n += 1
218242

219243
identities = []
220244
joiners = []
@@ -225,50 +249,50 @@ def from_signed_raw(cls, raw):
225249
transactions = []
226250

227251
if Block.re_identities.match(lines[n]) is not None:
228-
n = n + 1
252+
n += 1
229253
while Block.re_joiners.match(lines[n]) is None:
230254
selfcert = SelfCertification.from_inline(version, currency, lines[n])
231255
identities.append(selfcert)
232-
n = n + 1
256+
n += 1
233257

234258
if Block.re_joiners.match(lines[n]):
235-
n = n + 1
259+
n += 1
236260
while Block.re_actives.match(lines[n]) is None:
237261
membership = Membership.from_inline(version, currency, "IN", lines[n])
238262
joiners.append(membership)
239-
n = n + 1
263+
n += 1
240264

241265
if Block.re_actives.match(lines[n]):
242-
n = n + 1
266+
n += 1
243267
while Block.re_leavers.match(lines[n]) is None:
244268
membership = Membership.from_inline(version, currency, "IN", lines[n])
245269
actives.append(membership)
246-
n = n + 1
270+
n += 1
247271

248272
if Block.re_leavers.match(lines[n]):
249-
n = n + 1
273+
n += 1
250274
while Block.re_excluded.match(lines[n]) is None:
251275
membership = Membership.from_inline(version, currency, "OUT", lines[n])
252276
leavers.append(membership)
253-
n = n + 1
277+
n += 1
254278

255279
if Block.re_excluded.match(lines[n]):
256-
n = n + 1
280+
n += 1
257281
while Block.re_certifications.match(lines[n]) is None:
258282
membership = Block.re_exclusion.match(lines[n]).group(1)
259283
excluded.append(membership)
260-
n = n + 1
284+
n += 1
261285

262286
if Block.re_certifications.match(lines[n]):
263-
n = n + 1
287+
n += 1
264288
while Block.re_transactions.match(lines[n]) is None:
265289
certification = Certification.from_inline(version, currency,
266290
prev_hash, lines[n])
267291
certifications.append(certification)
268-
n = n + 1
292+
n += 1
269293

270294
if Block.re_transactions.match(lines[n]):
271-
n = n + 1
295+
n += 1
272296
while not Block.re_signature.match(lines[n]):
273297
tx_lines = ""
274298
header_data = Transaction.re_header.match(lines[n])
@@ -277,14 +301,14 @@ def from_signed_raw(cls, raw):
277301
inputs_num = int(header_data.group(3))
278302
outputs_num = int(header_data.group(4))
279303
has_comment = int(header_data.group(5))
280-
tx_max = n+issuers_num*2+inputs_num+outputs_num+has_comment+1
304+
tx_max = n + issuers_num * 2 + inputs_num + outputs_num + has_comment + 1
281305
for i in range(n, tx_max):
282306
tx_lines += lines[n]
283-
n = n + 1
307+
n += 1
284308
transaction = Transaction.from_compact(currency, tx_lines)
285309
transactions.append(transaction)
286310

287-
signature = Block.re_signature.match(lines[n]).group(1)
311+
signature = Block.parse_field("Signature", lines[n])
288312

289313
return cls(version, currency, noonce, number, powmin, time,
290314
mediantime, ud, issuer, prev_hash, prev_issuer,

ucoinpy/documents/certification.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import base64
33
import logging
44

5-
from .document import Document
5+
from .document import Document, MalformedDocumentError
66

77

88
class SelfCertification(Document):
@@ -26,6 +26,8 @@ def __init__(self, version, currency, pubkey, ts, uid, signature):
2626
@classmethod
2727
def from_inline(cls, version, currency, inline):
2828
selfcert_data = SelfCertification.re_inline.match(inline)
29+
if selfcert_data is None:
30+
raise MalformedDocumentError("Inline self certification")
2931
pubkey = selfcert_data.group(1)
3032
signature = selfcert_data.group(2)
3133
ts = int(selfcert_data.group(3))
@@ -63,6 +65,8 @@ def __init__(self, version, currency, pubkey_from, pubkey_to,
6365
@classmethod
6466
def from_inline(cls, version, currency, blockhash, inline):
6567
cert_data = Certification.re_inline.match(inline)
68+
if cert_data is None:
69+
raise MalformedDocumentError("Certification")
6670
pubkey_from = cert_data.group(1)
6771
pubkey_to = cert_data.group(2)
6872
blocknumber = int(cert_data.group(3))

ucoinpy/documents/document.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,42 @@
1-
import base58
21
import base64
32
import re
43
import logging
54
import hashlib
65

76

7+
class MalformedDocumentError(Exception):
8+
"""
9+
Malformed document exception
10+
"""
11+
def __init__(self, field_name):
12+
super().__init__("Could not parse field {0}".format(field_name))
13+
14+
815
class Document:
916
re_version = re.compile("Version: ([0-9]+)\n")
1017
re_currency = re.compile("Currency: ([^\n]+)\n")
1118
re_signature = re.compile("([A-Za-z0-9+/]+(?:=|==)?)\n")
1219

20+
fields_parsers = {
21+
"Version": re_version,
22+
"Currency": re_currency,
23+
"Signature": re_signature
24+
}
25+
26+
@classmethod
27+
def parse_field(cls, field_name, line):
28+
"""
29+
30+
:param field_name:
31+
:param line:
32+
:return:
33+
"""
34+
try:
35+
value = cls.fields_parsers[field_name].match(line).group(1)
36+
except AttributeError:
37+
raise MalformedDocumentError(field_name)
38+
return value
39+
1340
def __init__(self, version, currency, signatures):
1441
self.version = version
1542
self.currency = currency

0 commit comments

Comments
 (0)