fix: use _bitmask for seriallizing thresholdconditions

This commit is contained in:
diminator 2016-03-21 10:49:39 +01:00
parent 892ab74acc
commit bb88279b64
5 changed files with 48 additions and 11 deletions

View File

@ -1,4 +1,4 @@
from bigchaindb.crypto.buffer import MAX_SAFE_INTEGER
from bigchaindb.crypto.buffer import MAX_SAFE_INTEGER_JS
class BitmaskRegistry:
@ -18,7 +18,7 @@ class BitmaskRegistry:
Class implementing the given fulfillment type.
"""
# Determine type of condition
if bitmask > MAX_SAFE_INTEGER:
if bitmask > MAX_SAFE_INTEGER_JS:
raise ValueError('Bitmask {} is not supported'.format(bitmask))
for registered_type in BitmaskRegistry.registered_types:

View File

@ -12,7 +12,9 @@ MSBALL = ~REST
INT = 2 ** 31
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER
MAX_SAFE_INTEGER = 2 ** 53 - 1
# we don't use sys.maxint (= 2 ** 63 - 1) as this spec is inline with the ILP JavaScript reference implementation
# see https://interledger.org/
MAX_SAFE_INTEGER_JS = 2 ** 53 - 1
class UnsignedLEB128:
@ -24,7 +26,7 @@ class UnsignedLEB128:
seven least significant bits of the number represented.
see: https://en.wikipedia.org/wiki/LEB128 (ULEB128)
see http://grokbase.com/t/python/python-list/112e5jpc16/encoding
see: http://grokbase.com/t/python/python-list/112e5jpc16/encoding
"""
@ -166,7 +168,7 @@ class Predictor:
self.size += 1
elif val < 0:
raise ValueError('Variable length integer cannot be negative')
elif val > MAX_SAFE_INTEGER:
elif val > MAX_SAFE_INTEGER_JS:
raise ValueError('Variable length integer too large')
else:
# Calculate number of bits divided by seven

View File

@ -1,7 +1,7 @@
# Crypto Conditions
This spec is from the [**Interledger Protocol (ILP)**]
(https://github.com/interledger/five-bells-condition/tree/feature/binary-merkle-v2)
(https://interledger.org/five-bells-condition/spec.html)
## Motivation
@ -248,7 +248,7 @@ print(sha256fulfillment.validate() and \
RSA-SHA-256 is assigned the type bit 2<sup>1</sup> = 0x02.
**Warning:** not (yet) implemented in BigchainDB, for info see the [**ILP specification**](https://github.com/interledger/five-bells-condition/blob/feature/binary-merkle-v2/docs/spec.md)
**Warning:** not (yet) implemented in BigchainDB, for info see the [**ILP specification**](https://interledger.org/five-bells-condition/spec.html)
## ED25519-SHA-256
@ -284,7 +284,7 @@ The `MESSAGE_ID` represents an identifier for the message. All messages in a cry
The message to be signed is the concatenation of the `FIXED_PREFIX` and `DYNAMIC_MESSAGE`.
The `MESSAGE_ID`, `FIXED_PREFIX`, `DYNAMIC_MESSAGE_LENGTH` and `DYNAMIC_MESSAGE` fields have the same meaning as in the [**RSA-SHA-256 condition type**](https://github.com/interledger/five-bells-condition/blob/feature/binary-merkle-v2/docs/spec.md).
The `MESSAGE_ID`, `FIXED_PREFIX`, `DYNAMIC_MESSAGE_LENGTH` and `DYNAMIC_MESSAGE` fields have the same meaning as in the [**RSA-SHA-256 condition type**](https://interledger.org/five-bells-condition/spec.html).
### Usage
@ -297,7 +297,7 @@ sk = Ed25519SigningKey(b'9qLvREC54mhKYivr88VpckyVWdAFmifJpGjbvV5AiTRs')
vk = sk.get_verifying_key()
# Create an ED25519-SHA256 condition
ed25519_fulfillment = Ed25519Sha256Fulfillment()
ed25519_fulfill`nt = Ed25519Sha256Fulfillment()
ed25519_fulfillment.public_key = vk
ed25519_fulfillment.message_prefix = 'Hello world!'
ed25519_fulfillment.max_dynamic_message_length = 32 # defaults to 0

View File

@ -71,7 +71,8 @@ class Fulfillment(metaclass=ABCMeta):
from bigchaindb.crypto.bitmark_registry import BitmaskRegistry
cls = BitmaskRegistry.get_class_from_typebit(reader.read_var_uint())
cls_type = reader.read_var_uint()
cls = BitmaskRegistry.get_class_from_typebit(cls_type)
fulfillment = cls()
fulfillment.parse_payload(reader)
@ -151,7 +152,7 @@ class Fulfillment(metaclass=ABCMeta):
Serialized fulfillment
"""
writer = Writer()
writer.write_var_uint(self.bitmask)
writer.write_var_uint(self._bitmask)
self.write_payload(writer)
return b''.join(writer.components)

View File

@ -292,3 +292,37 @@ class TestBigchainILPThresholdSha256Fulfillment:
assert len(deserialized_fulfillment.get_all_subconditions()) == threshold
assert deserialized_fulfillment.serialize_uri() == fulfillment_uri
assert deserialized_fulfillment.validate()
def test_fulfillment_nested_and_or(self):
ilp_fulfillment_sha = Fulfillment.from_uri(self.FULFILLMENT_SHA256_ILP)
ilp_fulfillment_ed1 = Fulfillment.from_uri(self.FULFILLMENT_ED25519_ILP_2)
ilp_fulfillment_ed2 = Fulfillment.from_uri(self.FULFILLMENT_ED25519_ILP)
# 2-of-2 (AND with 2 inputs)
fulfillment = ThresholdSha256Fulfillment()
fulfillment.threshold = 2
fulfillment.add_subfulfillment(ilp_fulfillment_sha)
assert fulfillment.validate() is False
# 1-of-2 (OR with 2 inputs)
nested_fulfillment = ThresholdSha256Fulfillment()
nested_fulfillment.threshold = 1
nested_fulfillment.add_subfulfillment(ilp_fulfillment_ed1)
assert nested_fulfillment.validate() is True
nested_fulfillment.add_subfulfillment(ilp_fulfillment_ed2)
assert nested_fulfillment.validate() is True
fulfillment.add_subfulfillment(nested_fulfillment)
assert fulfillment.validate() is True
fulfillment_uri = fulfillment.serialize_uri()
deserialized_fulfillment = Fulfillment.from_uri(fulfillment_uri)
assert isinstance(deserialized_fulfillment, ThresholdSha256Fulfillment)
assert deserialized_fulfillment.threshold == 2
assert len(deserialized_fulfillment.subfulfillments) == 2
assert len(deserialized_fulfillment.subfulfillments[1].subfulfillments) == 1
assert len(deserialized_fulfillment.get_all_subconditions()) == 2
assert deserialized_fulfillment.serialize_uri() == fulfillment_uri
assert deserialized_fulfillment.validate()