Permalink
Browse files

add a base function for looping over a batch; fix batch import to cor…

…rectly check the last certificate in the batch;
  • Loading branch information...
1 parent 14fa7bb commit 06e5d9d60d3b7beb217859d93e0adc1cdf09cb71 Attila Oláh committed Mar 28, 2013
Showing with 52 additions and 45 deletions.
  1. +26 −19 prcert/extract.py
  2. +12 −8 prcert/format_cert.py
  3. +14 −18 prcert/verify.py
View
@@ -10,25 +10,20 @@
def extract_cert(batch, prime, format_result=None):
"""Extract a single cetrificate from a batch."""
# Decode and verify the certificate:
- current_cert = b''
- for part in batch:
- if part != NULL:
- current_cert += part
- else:
- current_prime, witness, pairs = get_prime(current_cert)
- if current_prime == prime:
- # Certificate found:
- if format_result is None:
- # No formatting, return native values:
- return witness, pairs
- if format_result == 'raw':
- # Raw data was requested:
- return current_cert
- return format_cert.format_cert((witness, pairs), format_result)
- if current_prime > prime:
- # Certificate not in batch:
- return
- current_cert = b''
+ for cert in loop_batch(batch):
+ current_prime, witness, pairs = get_prime(cert)
+ if current_prime == prime:
+ # Certificate found:
+ if format_result is None:
+ # No formatting, return native values:
+ return witness, pairs
+ if format_result == 'raw':
+ # Raw data was requested:
+ return cert
+ return format_cert.format_cert((witness, pairs), format_result)
+ if current_prime > prime:
+ # Certificate not in batch:
+ return
def get_prime(data):
@@ -37,3 +32,15 @@ def get_prime(data):
witness, pairs = varint.decode_cert(data)
prime = reduce(operator.mul, map(pow, *zip(*pairs))) + 1
return prime, witness, pairs
+
+
+def loop_batch(data):
+ """Loop over a batch, yielding certificates."""
+ current_cert = b''
+ for part in data:
+ if part != NULL:
+ current_cert += part
+ else:
+ yield current_cert
+ current_cert = b''
+ yield current_cert
View
@@ -12,7 +12,7 @@
{}
</factors>
<witness>{}</witness>
-</certificate>
+</certificate>\
'''
XML_FACTOR_TEMPLATE = b'''\
<factor>
@@ -22,21 +22,25 @@
'''
-def format_cert(cert, format_result=b'json'):
+def format_cert(cert, format_result=b'json', trailing_newline=True):
"""Format a single certificate."""
witness, pairs = cert
if format_result == b'json':
- return json.dumps({
+ result = json.dumps({
u'witness': witness,
u'factors': [{
u'base': base,
u'exponent': exponent,
} for base, exponent in pairs]}, indent=2, sort_keys=True)
- if format_result == b'xml':
- return XML_TEMPLATE.format(
+ elif format_result == b'xml':
+ result = XML_TEMPLATE.format(
b'\n'.join(XML_FACTOR_TEMPLATE.format(*pair) for pair in pairs), witness)
- if format_result == b'txt':
- return b' '.join((
+ elif format_result == b'txt':
+ result = b' '.join((
bytes(witness),
' '.join('{} {}'.format(*pair) for pair in pairs)))
- raise ValueError(u'Format must be one of {!r}, not {!r}.'.format(AVAILABLE_FORMATS, format_result))
+ else:
+ raise ValueError(u'Format must be one of {!r}, not {!r}.'.format(AVAILABLE_FORMATS, format_result))
+ if trailing_newline:
+ result += b'\n'
+ return result
View
@@ -5,6 +5,7 @@
from . import BATCH_SIZE
from . import NULL
from . import compress
+from . import extract
from . import get_batch_hash
from . import mesq
from . import varint
@@ -29,27 +30,22 @@ def batch(data, b_hash, b_size=BATCH_SIZE, recompress=None):
if not data:
return False
# Decode and verify the certificate:
- current_cert = b''
min_prime = max_prime = None
current_prime = previous_prime = None
- for part in data:
- if part != NULL:
- current_cert += part
+ for current_cert in extract.loop_batch(data):
+ previous_prime, current_prime = current_prime, cert(current_cert)
+ if not current_prime:
+ return False
+ if current_prime <= previous_prime:
+ return False
+ if min_prime is None:
+ min_prime = current_prime
+ else:
+ min_prime = min(min_prime, current_prime)
+ if max_prime is None:
+ max_prime = current_prime
else:
- previous_prime, current_prime = current_prime, cert(current_cert)
- if not current_prime:
- return False
- if current_prime <= previous_prime:
- return False
- if min_prime is None:
- min_prime = current_prime
- else:
- min_prime = min(min_prime, current_prime)
- if max_prime is None:
- max_prime = current_prime
- else:
- max_prime = max(max_prime, current_prime)
- current_cert = b''
+ max_prime = max(max_prime, current_prime)
# Make sure the batch size is not too large:
if min_prime>>b_size != max_prime>>b_size:
return False

0 comments on commit 06e5d9d

Please sign in to comment.