This commit is contained in:
diminator 2016-03-18 20:20:18 +01:00
parent 9bd1e9ff8b
commit bdc2475bdd
4 changed files with 61 additions and 59 deletions

View File

@ -50,11 +50,11 @@ class Condition(metaclass=ABCMeta):
@staticmethod @staticmethod
def from_binary(reader): def from_binary(reader):
""" """
* Create a Condition object from a binary blob. Create a Condition object from a binary blob.
*
* This method will parse a stream of binary data and construct a This method will parse a stream of binary data and construct a
* corresponding Condition object. corresponding Condition object.
*
Args: Args:
reader (Reader): Binary stream implementing the Reader interface reader (Reader): Binary stream implementing the Reader interface
Returns: Returns:
@ -207,14 +207,13 @@ class Condition(metaclass=ABCMeta):
writer.write_var_uint(self.max_fulfillment_length) writer.write_var_uint(self.max_fulfillment_length)
return b''.join(writer.components) return b''.join(writer.components)
def parse_binary(self, reader): def parse_binary(self, reader):
""" """
* Parse any condition in binary format. Parse any condition in binary format.
*
* Will populate the condition object with data from the provided binary Will populate the condition object with data from the provided binary
* stream. stream.
*
Args: Args:
reader (Reader): Binary stream containing the condition. reader (Reader): Binary stream containing the condition.
""" """

View File

@ -52,7 +52,8 @@ class ThresholdSha256Fulfillment(BaseSha256Fulfillment):
This method returns the subconditions plus all subfulfillments, converted to conditions. This method returns the subconditions plus all subfulfillments, converted to conditions.
@return {Condition[]} Set of subconditions Returns:
[Condition]: Set of subconditions
""" """
return self.subconditions + [f.condition for f in self.subfulfillments] return self.subconditions + [f.condition for f in self.subfulfillments]
@ -84,7 +85,8 @@ class ThresholdSha256Fulfillment(BaseSha256Fulfillment):
validate this fulfillment. Therefore, we need to calculate the bitwise OR validate this fulfillment. Therefore, we need to calculate the bitwise OR
of this condition's TYPE_BIT and all subcondition's and subfulfillment's bitmasks. of this condition's TYPE_BIT and all subcondition's and subfulfillment's bitmasks.
@return {Number} Complete bitmask for this fulfillment. Returns:
int: Complete bitmask for this fulfillment.
""" """
bitmask = self._bitmask bitmask = self._bitmask
@ -140,7 +142,8 @@ class ThresholdSha256Fulfillment(BaseSha256Fulfillment):
however, it does not need to provide the exact worst-case fulfillment however, it does not need to provide the exact worst-case fulfillment
length, only an upper bound for it. length, only an upper bound for it.
@return {Number} Maximum length of the fulfillment payload Return:
int Maximum length of the fulfillment payload
""" """
# TODO: Currently wrong # TODO: Currently wrong
@ -243,7 +246,8 @@ class ThresholdSha256Fulfillment(BaseSha256Fulfillment):
This will validate the subfulfillments and verify that there are enough This will validate the subfulfillments and verify that there are enough
subfulfillments to meet the threshold. subfulfillments to meet the threshold.
@return {Boolean} Whether this fulfillment is valid. Returns:
boolean: Whether this fulfillment is valid.
""" """
validations = [f.validate() for f in self.subfulfillments] validations = [f.validate() for f in self.subfulfillments]
return len([v for v in validations]) >= self.threshold return len([v for v in validations]) >= self.threshold

View File

@ -27,6 +27,7 @@ class UnsignedLEB128:
see http://grokbase.com/t/python/python-list/112e5jpc16/encoding see http://grokbase.com/t/python/python-list/112e5jpc16/encoding
""" """
@staticmethod @staticmethod
def encode(obj): def encode(obj):
out = [] out = []
@ -51,7 +52,6 @@ class UnsignedLEB128:
class Writer: class Writer:
def __init__(self): def __init__(self):
self.components = [] self.components = []
@ -96,16 +96,12 @@ class Writer:
class Hasher(Writer): class Hasher(Writer):
def __init__(self):
self.hash = None
super().__init__()
def __init__(self, algorithm): def __init__(self, algorithm):
if algorithm == 'sha256': if algorithm == 'sha256':
self.hash = hashlib.sha256() self.hash = hashlib.sha256()
else: else:
raise NotImplementedError raise NotImplementedError
super(Writer, self).__init__() super().__init__()
def write(self, in_bytes): def write(self, in_bytes):
""" """
@ -151,7 +147,6 @@ class Hasher(Writer):
class Predictor: class Predictor:
def __init__(self): def __init__(self):
self.size = 0 self.size = 0
@ -200,7 +195,6 @@ class Predictor:
class Reader: class Reader:
def __init__(self, buffer): def __init__(self, buffer):
self.buffer = buffer self.buffer = buffer
self.cursor = 0 self.cursor = 0

View File

@ -1,6 +1,6 @@
import binascii import binascii
from math import floor, ceil from math import ceil
import pytest import pytest
@ -125,6 +125,7 @@ class TestBigchainILPEd25519Sha256Fulfillment:
def test_deserialize_fulfillment(self): def test_deserialize_fulfillment(self):
fulfillment = Fulfillment.from_uri(self.FULFILLMENT_ED25519_ILP) fulfillment = Fulfillment.from_uri(self.FULFILLMENT_ED25519_ILP)
assert isinstance(fulfillment, Ed25519Sha256Fulfillment)
assert fulfillment.serialize_uri() == self.FULFILLMENT_ED25519_ILP assert fulfillment.serialize_uri() == self.FULFILLMENT_ED25519_ILP
assert fulfillment.condition.serialize_uri() == self.CONDITION_ED25519_ILP assert fulfillment.condition.serialize_uri() == self.CONDITION_ED25519_ILP
assert binascii.hexlify(fulfillment.condition.hash) == self.HASH_ED25519_HEX_ILP assert binascii.hexlify(fulfillment.condition.hash) == self.HASH_ED25519_HEX_ILP
@ -145,6 +146,7 @@ class TestBigchainILPEd25519Sha256Fulfillment:
assert fulfillment.validate() assert fulfillment.validate()
deserialized_fulfillment = Fulfillment.from_uri(fulfillment.serialize_uri()) deserialized_fulfillment = Fulfillment.from_uri(fulfillment.serialize_uri())
assert isinstance(deserialized_fulfillment, Ed25519Sha256Fulfillment)
assert deserialized_fulfillment.serialize_uri() == fulfillment.serialize_uri() assert deserialized_fulfillment.serialize_uri() == fulfillment.serialize_uri()
assert deserialized_fulfillment.condition.serialize_uri() == fulfillment.condition.serialize_uri() assert deserialized_fulfillment.condition.serialize_uri() == fulfillment.condition.serialize_uri()
assert deserialized_fulfillment.public_key.public_key.to_bytes() == fulfillment.public_key.public_key.to_bytes() assert deserialized_fulfillment.public_key.public_key.to_bytes() == fulfillment.public_key.public_key.to_bytes()
@ -195,14 +197,14 @@ class TestBigchainILPThresholdSha256Fulfillment:
assert ilp_fulfillment.validate() == True assert ilp_fulfillment.validate() == True
assert ilp_fulfillment_2.validate() == True assert ilp_fulfillment_2.validate() == True
THRESHOLD = 2 threshold = 2
# Create a threshold condition # Create a threshold condition
fulfillment = ThresholdSha256Fulfillment() fulfillment = ThresholdSha256Fulfillment()
fulfillment.add_subfulfillment(ilp_fulfillment) fulfillment.add_subfulfillment(ilp_fulfillment)
fulfillment.add_subfulfillment(ilp_fulfillment_2) fulfillment.add_subfulfillment(ilp_fulfillment_2)
fulfillment.add_subfulfillment(ilp_fulfillment_3) fulfillment.add_subfulfillment(ilp_fulfillment_3)
fulfillment.threshold = THRESHOLD # defaults to subconditions.length fulfillment.threshold = threshold # defaults to subconditions.length
assert fulfillment.condition.serialize_uri() == self.CONDITION_THRESHOLD_ED25519_ILP_2 assert fulfillment.condition.serialize_uri() == self.CONDITION_THRESHOLD_ED25519_ILP_2
# Note: If there are more than enough fulfilled subconditions, shorter # Note: If there are more than enough fulfilled subconditions, shorter
@ -212,13 +214,14 @@ class TestBigchainILPThresholdSha256Fulfillment:
assert fulfillment.validate() assert fulfillment.validate()
def test_deserialize_fulfillment(self): def test_deserialize_fulfillment(self):
NUM_FULFILLMENTS = 3 num_fulfillments = 3
THRESHOLD = 2 threshold = 2
fulfillment = Fulfillment.from_uri(self.FULFILLMENT_THRESHOLD_ED25519_ILP_2) fulfillment = Fulfillment.from_uri(self.FULFILLMENT_THRESHOLD_ED25519_ILP_2)
assert fulfillment.threshold == THRESHOLD assert isinstance(fulfillment, ThresholdSha256Fulfillment)
assert len(fulfillment.subfulfillments) == THRESHOLD assert fulfillment.threshold == threshold
assert len(fulfillment.get_all_subconditions()) == NUM_FULFILLMENTS assert len(fulfillment.subfulfillments) == threshold
assert len(fulfillment.get_all_subconditions()) == num_fulfillments
assert fulfillment.serialize_uri() == self.FULFILLMENT_THRESHOLD_ED25519_ILP_2 assert fulfillment.serialize_uri() == self.FULFILLMENT_THRESHOLD_ED25519_ILP_2
assert fulfillment.validate() assert fulfillment.validate()
assert isinstance(fulfillment.subfulfillments[0], Sha256Fulfillment) assert isinstance(fulfillment.subfulfillments[0], Sha256Fulfillment)
@ -228,35 +231,36 @@ class TestBigchainILPThresholdSha256Fulfillment:
def test_serialize_deserialize_fulfillment(self): def test_serialize_deserialize_fulfillment(self):
ilp_fulfillment = Fulfillment.from_uri(self.FULFILLMENT_ED25519_ILP) ilp_fulfillment = Fulfillment.from_uri(self.FULFILLMENT_ED25519_ILP)
NUM_FULFILLMENTS = 100 num_fulfillments = 100
THRESHOLD = ceil(NUM_FULFILLMENTS * 2 / 3) threshold = ceil(num_fulfillments * 2 / 3)
# Create a threshold condition # Create a threshold condition
fulfillment = ThresholdSha256Fulfillment() fulfillment = ThresholdSha256Fulfillment()
for i in range(NUM_FULFILLMENTS): for i in range(num_fulfillments):
fulfillment.add_subfulfillment(ilp_fulfillment) fulfillment.add_subfulfillment(ilp_fulfillment)
fulfillment.threshold = THRESHOLD fulfillment.threshold = threshold
fulfillment_uri = fulfillment.serialize_uri() fulfillment_uri = fulfillment.serialize_uri()
assert fulfillment.validate() assert fulfillment.validate()
deserialized_fulfillment = Fulfillment.from_uri(fulfillment_uri) deserialized_fulfillment = Fulfillment.from_uri(fulfillment_uri)
assert deserialized_fulfillment.threshold == THRESHOLD assert isinstance(deserialized_fulfillment, ThresholdSha256Fulfillment)
assert len(deserialized_fulfillment.subfulfillments) == THRESHOLD assert deserialized_fulfillment.threshold == threshold
assert len(deserialized_fulfillment.get_all_subconditions()) == NUM_FULFILLMENTS assert len(deserialized_fulfillment.subfulfillments) == threshold
assert len(deserialized_fulfillment.get_all_subconditions()) == num_fulfillments
assert deserialized_fulfillment.serialize_uri() == fulfillment_uri assert deserialized_fulfillment.serialize_uri() == fulfillment_uri
assert deserialized_fulfillment.validate() assert deserialized_fulfillment.validate()
def test_fulfillment_didnt_reach_threshold(self): def test_fulfillment_didnt_reach_threshold(self):
ilp_fulfillment = Fulfillment.from_uri(self.FULFILLMENT_ED25519_ILP) ilp_fulfillment = Fulfillment.from_uri(self.FULFILLMENT_ED25519_ILP)
THRESHOLD = 10 threshold = 10
# Create a threshold condition # Create a threshold condition
fulfillment = ThresholdSha256Fulfillment() fulfillment = ThresholdSha256Fulfillment()
fulfillment.threshold = THRESHOLD fulfillment.threshold = threshold
for i in range(THRESHOLD - 1): for i in range(threshold - 1):
fulfillment.add_subfulfillment(ilp_fulfillment) fulfillment.add_subfulfillment(ilp_fulfillment)
with pytest.raises(ValueError): with pytest.raises(ValueError):
@ -271,8 +275,9 @@ class TestBigchainILPThresholdSha256Fulfillment:
deserialized_fulfillment = Fulfillment.from_uri(fulfillment_uri) deserialized_fulfillment = Fulfillment.from_uri(fulfillment_uri)
assert deserialized_fulfillment.threshold == THRESHOLD assert isinstance(deserialized_fulfillment, ThresholdSha256Fulfillment)
assert len(deserialized_fulfillment.subfulfillments) == THRESHOLD assert deserialized_fulfillment.threshold == threshold
assert len(deserialized_fulfillment.get_all_subconditions()) == THRESHOLD assert len(deserialized_fulfillment.subfulfillments) == threshold
assert len(deserialized_fulfillment.get_all_subconditions()) == threshold
assert deserialized_fulfillment.serialize_uri() == fulfillment_uri assert deserialized_fulfillment.serialize_uri() == fulfillment_uri
assert deserialized_fulfillment.validate() assert deserialized_fulfillment.validate()