Merge pull request #355 from bigchaindb/feat/inverted-threshold-condition

Feat/inverted threshold condition
This commit is contained in:
Dimitri De Jonghe 2016-06-10 14:06:27 +02:00 committed by GitHub
commit b651a8b7fa
6 changed files with 41 additions and 21 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 53 KiB

View File

@ -1035,15 +1035,14 @@ The above switch can be implemented as follows using threshold cryptoconditions:
<img width="100%" height="100%" src ="../_static/cc_escrow_execute_abort.png" />
</p>
The small circle (&#9898;) at an input of a threshold condition denotes an inversion of the fulfillment:
The inverted timeout is denoted by a -1 threshold, which negates the output of the fulfillment.
```python
inverted_fulfillment.validate(msg) == not fulfillment.validate(msg)
```
An inverted input to a threshold condition is simply obtained by negative weights.
__Note__: negative weights are BigchainDB-specific and not (yet) supported by the ILP standard.
__Note__: inverted thresholds are BigchainDB-specific and not supported by the ILP standard.
The main reason is that it's difficult to tell whether the fulfillment was negated, or just omitted.
The following code snippet shows how to create an escrow condition:
@ -1062,6 +1061,8 @@ time_expire = str(float(util.timestamp()) + time_sleep) # 12 secs from now
# Create the escrow and timeout condition
condition_escrow = cc.ThresholdSha256Fulfillment(threshold=1) # OR Gate
condition_timeout = cc.TimeoutFulfillment(expire_time=time_expire) # only valid if now() <= time_expire
condition_timeout_inverted = cc.InvertedThresholdSha256Fulfillment(threshold=1)
condition_timeout_inverted.add_subfulfillment(condition_timeout) # invert the timeout condition
# Create the execute branch
condition_execute = cc.ThresholdSha256Fulfillment(threshold=2) # AND gate
@ -1072,7 +1073,7 @@ condition_escrow.add_subfulfillment(condition_execute)
# Create the abort branch
condition_abort = cc.ThresholdSha256Fulfillment(threshold=2) # AND gate
condition_abort.add_subfulfillment(cc.Ed25519Fulfillment(public_key=testuser2_pub)) # abort address
condition_abort.add_subfulfillment(condition_timeout, weight=-1) # the negative weight inverts the condition
condition_abort.add_subfulfillment(condition_timeout_inverted)
condition_escrow.add_subfulfillment(condition_abort)
# Update the condition in the newly created transaction
@ -1142,10 +1143,19 @@ tx_escrow_signed
},
{
"bitmask":9,
"expire_time":"1464242352.227917",
"subfulfillments":[
{
"bitmask":9,
"expire_time":"1464242352.227917",
"type":"fulfillment",
"type_id":99,
"weight":1
}
],
"threshold":1,
"type":"fulfillment",
"type_id":99,
"weight":-1
"type_id":98,
"weight":1
}
],
"threshold":2,
@ -1205,6 +1215,7 @@ escrow_fulfillment = cc.Fulfillment.from_json(
subfulfillment_testuser1 = escrow_fulfillment.get_subcondition_from_vk(testuser1_pub)[0]
subfulfillment_testuser2 = escrow_fulfillment.get_subcondition_from_vk(testuser2_pub)[0]
subfulfillment_timeout = escrow_fulfillment.subconditions[0]['body'].subconditions[1]['body']
subfulfillment_timeout_inverted = escrow_fulfillment.subconditions[1]['body'].subconditions[1]['body']
# Get the fulfillment message to sign
tx_escrow_execute_fulfillment_message = \
@ -1225,7 +1236,7 @@ escrow_fulfillment.add_subfulfillment(fulfillment_execute)
# Do not fulfill the abort branch
condition_abort = cc.ThresholdSha256Fulfillment(threshold=2)
condition_abort.add_subfulfillment(subfulfillment_testuser2)
condition_abort.add_subfulfillment(subfulfillment_timeout, weight=-1)
condition_abort.add_subfulfillment(subfulfillment_timeout_inverted)
escrow_fulfillment.add_subcondition(condition_abort.condition) # Adding only the condition here
# Update the execute transaction with the fulfillment
@ -1245,6 +1256,7 @@ escrow_fulfillment = cc.Fulfillment.from_json(
subfulfillment_testuser1 = escrow_fulfillment.get_subcondition_from_vk(testuser1_pub)[0]
subfulfillment_testuser2 = escrow_fulfillment.get_subcondition_from_vk(testuser2_pub)[0]
subfulfillment_timeout = escrow_fulfillment.subconditions[0]['body'].subconditions[1]['body']
subfulfillment_timeout_inverted = escrow_fulfillment.subconditions[1]['body'].subconditions[1]['body']
# Get the fulfillment message to sign
tx_escrow_abort_fulfillment_message = \
@ -1265,7 +1277,7 @@ escrow_fulfillment.add_subcondition(condition_execute.condition) # Adding only t
fulfillment_abort = cc.ThresholdSha256Fulfillment(threshold=2)
subfulfillment_testuser2.sign(tx_escrow_abort_fulfillment_message, crypto.SigningKey(testuser2_priv))
fulfillment_abort.add_subfulfillment(subfulfillment_testuser2)
fulfillment_abort.add_subfulfillment(subfulfillment_timeout, weight=-1)
fulfillment_abort.add_subfulfillment(subfulfillment_timeout_inverted)
escrow_fulfillment.add_subfulfillment(fulfillment_abort)
# Update the abort transaction with the fulfillment

View File

@ -95,7 +95,7 @@ setup(
'rethinkdb==2.3.0',
'pysha3==0.3',
'pytz==2015.7',
'cryptoconditions==0.3.0',
'cryptoconditions==0.3.1',
'statsd==3.2.1',
'python-rapidjson==0.0.6',
'logstats==0.2.1',

View File

@ -2031,6 +2031,8 @@ class TestCryptoconditions(object):
condition_escrow = cc.ThresholdSha256Fulfillment(threshold=1)
fulfillment_timeout = cc.TimeoutFulfillment(expire_time=str(float(util.timestamp()) + time_sleep))
fulfillment_timeout_inverted = cc.InvertedThresholdSha256Fulfillment(threshold=1)
fulfillment_timeout_inverted.add_subfulfillment(fulfillment_timeout) # invert the timeout condition
condition_user = cc.Ed25519Fulfillment(public_key=user_vk)
condition_user2 = cc.Ed25519Fulfillment(public_key=user2_vk)
@ -2042,7 +2044,7 @@ class TestCryptoconditions(object):
# do not fulfill abort branch
fulfillment_and_abort = cc.ThresholdSha256Fulfillment(threshold=2)
fulfillment_and_abort.add_subfulfillment(condition_user)
fulfillment_and_abort.add_subfulfillment(fulfillment_timeout, weight=-1)
fulfillment_and_abort.add_subfulfillment(fulfillment_timeout_inverted)
condition_escrow.add_subfulfillment(fulfillment_and_execute)
condition_escrow.add_subfulfillment(fulfillment_and_abort)
@ -2096,7 +2098,7 @@ class TestCryptoconditions(object):
# do not fulfill abort branch
fulfillment_and_abort = cc.ThresholdSha256Fulfillment(threshold=2)
fulfillment_and_abort.add_subfulfillment(subfulfillment_user)
fulfillment_and_abort.add_subfulfillment(fulfillment_timeout, weight=-1)
fulfillment_and_abort.add_subfulfillment(fulfillment_timeout_inverted)
escrow_fulfillment.add_subcondition(fulfillment_and_abort.condition)
escrow_tx_transfer['transaction']['fulfillments'][0]['fulfillment'] = escrow_fulfillment.serialize_uri()
@ -2137,7 +2139,7 @@ class TestCryptoconditions(object):
fulfillment_and_abort = cc.ThresholdSha256Fulfillment(threshold=2)
subfulfillment_user.sign(escrow_tx_fulfillment_message, crypto.SigningKey(user_sk))
fulfillment_and_abort.add_subfulfillment(subfulfillment_user)
fulfillment_and_abort.add_subfulfillment(fulfillment_timeout, weight=-1)
fulfillment_and_abort.add_subfulfillment(fulfillment_timeout_inverted)
escrow_fulfillment.add_subfulfillment(fulfillment_and_abort)
escrow_tx_abort['transaction']['fulfillments'][0]['fulfillment'] = escrow_fulfillment.serialize_uri()
@ -2158,6 +2160,8 @@ class TestCryptoconditions(object):
condition_escrow = cc.ThresholdSha256Fulfillment(threshold=1)
fulfillment_timeout = cc.TimeoutFulfillment(expire_time=str(float(util.timestamp()) + time_sleep))
fulfillment_timeout_inverted = cc.InvertedThresholdSha256Fulfillment(threshold=1)
fulfillment_timeout_inverted.add_subfulfillment(fulfillment_timeout) # invert the timeout condition
condition_user = cc.Ed25519Fulfillment(public_key=user_vk)
condition_user2 = cc.Ed25519Fulfillment(public_key=user2_vk)
@ -2169,7 +2173,7 @@ class TestCryptoconditions(object):
# do not fulfill abort branch
fulfillment_and_abort = cc.ThresholdSha256Fulfillment(threshold=2)
fulfillment_and_abort.add_subfulfillment(condition_user)
fulfillment_and_abort.add_subfulfillment(fulfillment_timeout, weight=-1)
fulfillment_and_abort.add_subfulfillment(fulfillment_timeout_inverted)
condition_escrow.add_subfulfillment(fulfillment_and_execute)
condition_escrow.add_subfulfillment(fulfillment_and_abort)
@ -2223,7 +2227,7 @@ class TestCryptoconditions(object):
# do not fulfill abort branch
fulfillment_and_abort = cc.ThresholdSha256Fulfillment(threshold=2)
fulfillment_and_abort.add_subfulfillment(subfulfillment_user)
fulfillment_and_abort.add_subfulfillment(fulfillment_timeout, weight=-1)
fulfillment_and_abort.add_subfulfillment(fulfillment_timeout_inverted)
escrow_fulfillment.add_subcondition(fulfillment_and_abort.condition)
escrow_tx_transfer['transaction']['fulfillments'][0]['fulfillment'] = escrow_fulfillment.serialize_uri()
@ -2270,7 +2274,7 @@ class TestCryptoconditions(object):
fulfillment_and_abort = cc.ThresholdSha256Fulfillment(threshold=2)
subfulfillment_user.sign(escrow_tx_fulfillment_message, crypto.SigningKey(user_sk))
fulfillment_and_abort.add_subfulfillment(subfulfillment_user)
fulfillment_and_abort.add_subfulfillment(fulfillment_timeout, weight=-1)
fulfillment_and_abort.add_subfulfillment(fulfillment_timeout_inverted)
escrow_fulfillment.add_subfulfillment(fulfillment_and_abort)
escrow_tx_abort['transaction']['fulfillments'][0]['fulfillment'] = escrow_fulfillment.serialize_uri()

View File

@ -119,7 +119,7 @@ tx_multisig_transfer_signed = b.sign_transaction(tx_multisig_transfer, [testuser
try:
b.validate_transaction(tx_multisig_transfer_signed)
except exceptions.InvalidSignature:
import ipdb; ipdb.set_trace()
# import ipdb; ipdb.set_trace()
b.validate_transaction(tx_multisig_transfer_signed)
b.write_transaction(tx_multisig_transfer_signed)
@ -375,6 +375,8 @@ time_expire = str(float(util.timestamp()) + time_sleep)
# Create escrow and timeout condition
condition_escrow = cc.ThresholdSha256Fulfillment(threshold=1) # OR Gate
condition_timeout = cc.TimeoutFulfillment(expire_time=time_expire) # only valid if now() <= time_expire
condition_timeout_inverted = cc.InvertedThresholdSha256Fulfillment(threshold=1)
condition_timeout_inverted.add_subfulfillment(condition_timeout)
# Create execute branch
condition_execute = cc.ThresholdSha256Fulfillment(threshold=2) # AND gate
@ -385,7 +387,7 @@ condition_escrow.add_subfulfillment(condition_execute)
# Create abort branch
condition_abort = cc.ThresholdSha256Fulfillment(threshold=2) # AND gate
condition_abort.add_subfulfillment(cc.Ed25519Fulfillment(public_key=testuser2_pub)) # abort address
condition_abort.add_subfulfillment(condition_timeout, weight=-1) # the negative weight inverts the condition
condition_abort.add_subfulfillment(condition_timeout_inverted)
condition_escrow.add_subfulfillment(condition_abort)
# Update the condition in the newly created transaction
@ -421,6 +423,7 @@ escrow_fulfillment = cc.Fulfillment.from_json(
subfulfillment_testuser1 = escrow_fulfillment.get_subcondition_from_vk(testuser1_pub)[0]
subfulfillment_testuser2 = escrow_fulfillment.get_subcondition_from_vk(testuser2_pub)[0]
subfulfillment_timeout = escrow_fulfillment.subconditions[0]['body'].subconditions[1]['body']
subfulfillment_timeout_inverted = escrow_fulfillment.subconditions[1]['body'].subconditions[1]['body']
# Get the fulfillment message to sign
tx_escrow_execute_fulfillment_message = \
@ -440,7 +443,7 @@ escrow_fulfillment.add_subfulfillment(fulfillment_execute)
# do not fulfill abort branch
condition_abort = cc.ThresholdSha256Fulfillment(threshold=2)
condition_abort.add_subfulfillment(subfulfillment_testuser2)
condition_abort.add_subfulfillment(subfulfillment_timeout, weight=-1)
condition_abort.add_subfulfillment(subfulfillment_timeout_inverted)
escrow_fulfillment.add_subcondition(condition_abort.condition)
# create fulfillment and append to transaction
@ -456,6 +459,7 @@ escrow_fulfillment = cc.Fulfillment.from_json(
subfulfillment_testuser1 = escrow_fulfillment.get_subcondition_from_vk(testuser1_pub)[0]
subfulfillment_testuser2 = escrow_fulfillment.get_subcondition_from_vk(testuser2_pub)[0]
subfulfillment_timeout = escrow_fulfillment.subconditions[0]['body'].subconditions[1]['body']
subfulfillment_timeout_inverted = escrow_fulfillment.subconditions[1]['body'].subconditions[1]['body']
tx_escrow_abort_fulfillment_message = \
util.get_fulfillment_message(tx_escrow_abort,
@ -473,7 +477,7 @@ escrow_fulfillment.add_subcondition(condition_execute.condition)
fulfillment_abort = cc.ThresholdSha256Fulfillment(threshold=2)
subfulfillment_testuser2.sign(tx_escrow_abort_fulfillment_message, crypto.SigningKey(testuser2_priv))
fulfillment_abort.add_subfulfillment(subfulfillment_testuser2)
fulfillment_abort.add_subfulfillment(subfulfillment_timeout, weight=-1)
fulfillment_abort.add_subfulfillment(subfulfillment_timeout_inverted)
escrow_fulfillment.add_subfulfillment(fulfillment_abort)
tx_escrow_abort['transaction']['fulfillments'][0]['fulfillment'] = escrow_fulfillment.serialize_uri()