diff --git a/CHANGELOG.md b/CHANGELOG.md index 11a14da2..ad931721 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,12 +15,28 @@ For reference, the possible headings are: * **Notes** -## [Unreleased] - YYYY-MM-DD -Tag name: +## [0.4.1] - 2016-06-13 +Tag name: v0.4.1 = commit: committed: -(Add new stuff here from time to time until the next version release.) +### Added +- Revert `bigchain` deletes: [Pull Request #330](https://github.com/bigchaindb/bigchaindb/pull/330) + +### Changed +- Use inverted threshold condition instead of negative weights for escrow: [Pull Request #355](https://github.com/bigchaindb/bigchaindb/pull/355) + +### Fixed +- Removed duplicate `pytest` in `setup.py`: [Pull Request #365](https://github.com/bigchaindb/bigchaindb/pull/365) + +### Notes +- There were several additions and changes to the documentation: Pull Requests +[#343](https://github.com/bigchaindb/bigchaindb/pull/343), +[#363](https://github.com/bigchaindb/bigchaindb/pull/363), +[#364](https://github.com/bigchaindb/bigchaindb/pull/364), +[#366](https://github.com/bigchaindb/bigchaindb/pull/366), +[#370](https://github.com/bigchaindb/bigchaindb/pull/370), +[#372](https://github.com/bigchaindb/bigchaindb/pull/372) ## [0.4.0] - 2016-05-27 diff --git a/bigchaindb/version.py b/bigchaindb/version.py index f892d89f..ce4b94e3 100644 --- a/bigchaindb/version.py +++ b/bigchaindb/version.py @@ -1,2 +1,2 @@ -__version__ = '0.4.0' -__short_version__ = '0.4' \ No newline at end of file +__version__ = '0.4.1' +__short_version__ = '0.4' diff --git a/docs/source/_static/cc_escrow_execute_abort.png b/docs/source/_static/cc_escrow_execute_abort.png index e2c61217..959f276f 100644 Binary files a/docs/source/_static/cc_escrow_execute_abort.png and b/docs/source/_static/cc_escrow_execute_abort.png differ diff --git a/docs/source/_static/tx_schematics.odg b/docs/source/_static/tx_schematics.odg index c367dec9..49453f8b 100644 Binary files a/docs/source/_static/tx_schematics.odg and b/docs/source/_static/tx_schematics.odg differ diff --git a/docs/source/nodes/python-server-api-examples.md b/docs/source/nodes/python-server-api-examples.md index 9c2e7593..8aa97ee1 100644 --- a/docs/source/nodes/python-server-api-examples.md +++ b/docs/source/nodes/python-server-api-examples.md @@ -1035,15 +1035,14 @@ The above switch can be implemented as follows using threshold cryptoconditions:

-The small circle (⚪) 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 diff --git a/setup.py b/setup.py index 2924a455..e3290394 100644 --- a/setup.py +++ b/setup.py @@ -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', diff --git a/tests/db/test_bigchain_api.py b/tests/db/test_bigchain_api.py index d8389f91..33643c9b 100644 --- a/tests/db/test_bigchain_api.py +++ b/tests/db/test_bigchain_api.py @@ -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() diff --git a/tests/doc/run_doc_python_server_api_examples.py b/tests/doc/run_doc_python_server_api_examples.py index 5ae9300f..2e132b04 100644 --- a/tests/doc/run_doc_python_server_api_examples.py +++ b/tests/doc/run_doc_python_server_api_examples.py @@ -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()