diff --git a/acceptance/python/src/conftest.py b/acceptance/python/src/conftest.py index 747e527..4e658fa 100644 --- a/acceptance/python/src/conftest.py +++ b/acceptance/python/src/conftest.py @@ -81,6 +81,7 @@ def zenroom_script_input(): return SCRIPT_INPUT + @pytest.fixture def zenroom_data(): return ZENROOM_DATA diff --git a/acceptance/python/src/test_zenroom.py b/acceptance/python/src/test_zenroom.py index 82a9880..d50c111 100644 --- a/acceptance/python/src/test_zenroom.py +++ b/acceptance/python/src/test_zenroom.py @@ -38,6 +38,26 @@ def test_zenroom_signing( zenroomscpt = ZenroomSha256(script=fulfill_script_zencode, data=zenroom_data, keys=zen_public_keys) print(f"zenroom is: {zenroomscpt.script}") +def test_zenroom_signing(gen_key_zencode, secret_key_to_private_key_zencode, + fulfill_script_zencode, zenroom_data, zenroom_house_assets, + condition_script_zencode): + + biolabs = generate_keypair() + version = '2.0' + + alice = json.loads(zencode_exec(gen_key_zencode).output)['keyring'] + bob = json.loads(zencode_exec(gen_key_zencode).output)['keyring'] + + zen_public_keys = json.loads(zencode_exec(secret_key_to_private_key_zencode.format('Alice'), + keys=json.dumps({'keyring': alice})).output) + zen_public_keys.update(json.loads(zencode_exec(secret_key_to_private_key_zencode.format('Bob'), + keys=json.dumps({'keyring': bob})).output)) + + + + zenroomscpt = ZenroomSha256(script=fulfill_script_zencode, data=zenroom_data, keys=zen_public_keys) + print(F'zenroom is: {zenroomscpt.script}') + # CRYPTO-CONDITIONS: generate the condition uri condition_uri_zen = zenroomscpt.condition.serialize_uri() print(f"\nzenroom condition URI: {condition_uri_zen}") @@ -73,7 +93,12 @@ def test_zenroom_signing( "output": ["ok"], "policies": {}, } - + metadata = { + "result": { + "output": ["ok"] + } + } + token_creation_tx = { "operation": "CREATE", "asset": {"data": multihash(marshal({"test": "my asset"}))}, diff --git a/docs/root/source/basic-usage.md b/docs/root/source/basic-usage.md index 16d9490..844c309 100644 --- a/docs/root/source/basic-usage.md +++ b/docs/root/source/basic-usage.md @@ -151,6 +151,7 @@ and Planetmint has been developed with simple logical gateways in mind. The logic got introduced by [cryptoconditions](https://https://docs.planetmint.io/projects/cryptoconditions). The cryptocondition documentation contains all details about how conditoins are defined and how they can be verified and fulfilled. +<<<<<<< HEAD The integration of such into the transaction schema of Planetmint is shown below. ## Zenroom Smart Contracts and Policies @@ -159,3 +160,6 @@ The integration of such into the transaction schema of Planetmint is shown below At the moment these contracts can only be stateless, which implies that the conditions and fulfillments need to be transacted in the same transaction. However, [PRP-10](https://github.com/planetmint/PRPs/tree/main/10) aims to make stateful contracts possible, which enables asynchronous and party-independent processing of contracts. As for network-wide or asset-based policies [PRP-11](https://github.com/planetmint/PRPs/tree/main/11) specifies how these can be implemented and how these can be used to verify a transaction state before it is commited to the network. +======= +The integration of such into the transaction schema of Planetmint is shown below. +>>>>>>> planetmint-tarantool diff --git a/docs/root/source/connecting/http-samples/api-index-response.http b/docs/root/source/connecting/http-samples/api-index-response.http index 0b0deb8..05eaa23 100644 --- a/docs/root/source/connecting/http-samples/api-index-response.http +++ b/docs/root/source/connecting/http-samples/api-index-response.http @@ -4,7 +4,7 @@ Content-Type: application/json { "assets": "/assets/", "blocks": "/blocks/", - "docs": "https://docs.planetmint.io/projects/server/en/v1.0.1/http-client-server-api.html", + "docs": "https://docs.planetmint.io/projects/server/en/v1.2.2/http-client-server-api.html", "metadata": "/metadata/", "outputs": "/outputs/", "streamedblocks": "ws://localhost:9985/api/v1/streams/valid_blocks", diff --git a/docs/root/source/connecting/http-samples/get-block-response.http b/docs/root/source/connecting/http-samples/get-block-response.http index 168c60c..d3c6ceb 100644 --- a/docs/root/source/connecting/http-samples/get-block-response.http +++ b/docs/root/source/connecting/http-samples/get-block-response.http @@ -6,23 +6,19 @@ Content-Type: application/json "transactions": [ { "asset": { - "data": { - "msg": "Hello Planetmint!" - } + "data": "QmQP5C3PmhH9oB84n7YqSY4WVqmYatdoo1BdwhH4zmcwqM" }, - "id": "6438c733f53dff60bdeded80e8c95126dd3a7ce8c1ee5d5591d030e61cde35d2", + "id": "e4ebc02324e10925226bf2143363c1a28481ee38f70a9245a5a76df5f4380a7a", "inputs": [ { - "fulfillment": "pGSAIDE5i63cn4X8T8N1sZ2mGkJD5lNRnBM4PZgI_zvzbr-cgUBcdRj6EnG3MPl47m3XPd1HNfe7q3WL4T6MewNNnat33UvzVnPHo_vossv57M7L064VwrYMLGp097H7IeHpDngK", + "fulfillment": "pGSAIDE5i63cn4X8T8N1sZ2mGkJD5lNRnBM4PZgI_zvzbr-cgUDVDqtaQTYon0UJ-k2YEGfKfDWAwz9BnfBPkKvSHAgfU5O-1S8eY4mNjHAQConK47tnE7ksezmOrLL0_DR1Mm0P", "fulfills": null, "owners_before": [ "4K9sWUMFwTgaDGPfdynrbxWqWS6sWmKbZoTjxLtVUibD" ] } ], - "metadata": { - "sequence": 0 - }, + "metadata": "QmZs4UHLHCUGLQr6rzbtJTjT8Sf5pw6FNuaRZ5pzguk5FV", "operation": "CREATE", "outputs": [ { diff --git a/docs/root/source/connecting/http-samples/get-block-txid-request.http b/docs/root/source/connecting/http-samples/get-block-txid-request.http index 7ecb018..276d9a1 100644 --- a/docs/root/source/connecting/http-samples/get-block-txid-request.http +++ b/docs/root/source/connecting/http-samples/get-block-txid-request.http @@ -1,3 +1,3 @@ -GET /api/v1/blocks?transaction_id=6438c733f53dff60bdeded80e8c95126dd3a7ce8c1ee5d5591d030e61cde35d2 HTTP/1.1 +GET /api/v1/blocks?transaction_id=e4ebc02324e10925226bf2143363c1a28481ee38f70a9245a5a76df5f4380a7a HTTP/1.1 Host: example.com diff --git a/docs/root/source/connecting/http-samples/get-tx-by-asset-request.http b/docs/root/source/connecting/http-samples/get-tx-by-asset-request.http index fb15c84..5a7ee61 100644 --- a/docs/root/source/connecting/http-samples/get-tx-by-asset-request.http +++ b/docs/root/source/connecting/http-samples/get-tx-by-asset-request.http @@ -1,3 +1,3 @@ -GET /api/v1/transactions?operation=TRANSFER&asset_id=6438c733f53dff60bdeded80e8c95126dd3a7ce8c1ee5d5591d030e61cde35d2 HTTP/1.1 +GET /api/v1/transactions?operation=TRANSFER&asset_id=e4ebc02324e10925226bf2143363c1a28481ee38f70a9245a5a76df5f4380a7a HTTP/1.1 Host: example.com diff --git a/docs/root/source/connecting/http-samples/get-tx-by-asset-response.http b/docs/root/source/connecting/http-samples/get-tx-by-asset-response.http index 6ed97dc..b4cf2b7 100644 --- a/docs/root/source/connecting/http-samples/get-tx-by-asset-response.http +++ b/docs/root/source/connecting/http-samples/get-tx-by-asset-response.http @@ -3,24 +3,22 @@ Content-Type: application/json [{ "asset": { - "id": "6438c733f53dff60bdeded80e8c95126dd3a7ce8c1ee5d5591d030e61cde35d2" + "id": "e4ebc02324e10925226bf2143363c1a28481ee38f70a9245a5a76df5f4380a7a" }, - "id": "2bf8ae1e3bc889a26df129dd6bbe6ccab30d1ae8e9e434fae1c4446042a68931", + "id": "b3f39407b3907587de26bedec93cd6b2c6958bca90f77349f1db9780f014bc1f", "inputs": [ { - "fulfillment": "pGSAIDE5i63cn4X8T8N1sZ2mGkJD5lNRnBM4PZgI_zvzbr-cgUA90mMa9AWnbI70CUSVgzV9kRFf3tQ20RUIczNFqmwg9xrpOk_5uNoJB4bWRIojZmUhEyxSueCHLpqPXCEuyisE", + "fulfillment": "pGSAIDE5i63cn4X8T8N1sZ2mGkJD5lNRnBM4PZgI_zvzbr-cgUCtt9Thk_enrynxclNFj8B76QvIFbvhyj_38wuy1vA-lncUb2Q7bwJvnmmufeXucyEBTZQ0xoI5dfjG3KeTsLkH", "fulfills": { "output_index": 0, - "transaction_id": "6438c733f53dff60bdeded80e8c95126dd3a7ce8c1ee5d5591d030e61cde35d2" + "transaction_id": "e4ebc02324e10925226bf2143363c1a28481ee38f70a9245a5a76df5f4380a7a" }, "owners_before": [ "4K9sWUMFwTgaDGPfdynrbxWqWS6sWmKbZoTjxLtVUibD" ] } ], - "metadata": { - "sequence": 1 - }, + "metadata": "QmQ9Sc3VWZ3nH5FWVVi2MNMDhyjTiKrEb6mN79qqt1Uq9s", "operation": "TRANSFER", "outputs": [ { @@ -41,24 +39,22 @@ Content-Type: application/json }, { "asset": { - "id": "6438c733f53dff60bdeded80e8c95126dd3a7ce8c1ee5d5591d030e61cde35d2" + "id": "e4ebc02324e10925226bf2143363c1a28481ee38f70a9245a5a76df5f4380a7a" }, - "id": "b9b614175eaed7cc93d9b80ebc2a91d35ae31928a7c218ae982272bb1785ef16", + "id": "95d99c245cd83af10f3c8ba6c32eda7cb668698b5aaaeec67be3faf915bb6b5d", "inputs": [ { - "fulfillment": "pGSAICw7Ul-c2lG6NFbHp3FbKRC7fivQcNGO7GS4wV3A-1QggUDi2bAVKJgEyE3LzMrAnAu1PnNs9DbDNkABaY6j3OCNEVwNVNg3V3qELOFNnH8vGUevREr4E-8Vb1Kzk4VR71MO", + "fulfillment": "pGSAICw7Ul-c2lG6NFbHp3FbKRC7fivQcNGO7GS4wV3A-1QggUA2Z5Iw7YlMO0K9H_qcfGyepj6rqODxUZSysK_QS_tiZSlSdkXzCSLRCDO07EsyeBKEUUXpWHoBUv1lqJhFtjUK", "fulfills": { "output_index": 0, - "transaction_id": "2bf8ae1e3bc889a26df129dd6bbe6ccab30d1ae8e9e434fae1c4446042a68931" + "transaction_id": "b3f39407b3907587de26bedec93cd6b2c6958bca90f77349f1db9780f014bc1f" }, "owners_before": [ "3yfQPHeWAa1MxTX9Zf9176QqcpcnWcanVZZbaHb8B3h9" ] } ], - "metadata": { - "sequence": 2 - }, + "metadata": "QmRRg9RGq3TmV6nj2SXJacPuTdwaFDGTPACJLdN368pN3t", "operation": "TRANSFER", "outputs": [ { diff --git a/docs/root/source/connecting/http-samples/get-tx-id-request.http b/docs/root/source/connecting/http-samples/get-tx-id-request.http index c6c834c..f2bef71 100644 --- a/docs/root/source/connecting/http-samples/get-tx-id-request.http +++ b/docs/root/source/connecting/http-samples/get-tx-id-request.http @@ -1,3 +1,3 @@ -GET /api/v1/transactions/6438c733f53dff60bdeded80e8c95126dd3a7ce8c1ee5d5591d030e61cde35d2 HTTP/1.1 +GET /api/v1/transactions/e4ebc02324e10925226bf2143363c1a28481ee38f70a9245a5a76df5f4380a7a HTTP/1.1 Host: example.com diff --git a/docs/root/source/connecting/http-samples/get-tx-id-response.http b/docs/root/source/connecting/http-samples/get-tx-id-response.http index c5f3b71..f1b75ec 100644 --- a/docs/root/source/connecting/http-samples/get-tx-id-response.http +++ b/docs/root/source/connecting/http-samples/get-tx-id-response.http @@ -3,23 +3,19 @@ Content-Type: application/json { "asset": { - "data": { - "msg": "Hello Planetmint!" - } + "data": "QmQP5C3PmhH9oB84n7YqSY4WVqmYatdoo1BdwhH4zmcwqM" }, - "id": "6438c733f53dff60bdeded80e8c95126dd3a7ce8c1ee5d5591d030e61cde35d2", + "id": "e4ebc02324e10925226bf2143363c1a28481ee38f70a9245a5a76df5f4380a7a", "inputs": [ { - "fulfillment": "pGSAIDE5i63cn4X8T8N1sZ2mGkJD5lNRnBM4PZgI_zvzbr-cgUBcdRj6EnG3MPl47m3XPd1HNfe7q3WL4T6MewNNnat33UvzVnPHo_vossv57M7L064VwrYMLGp097H7IeHpDngK", + "fulfillment": "pGSAIDE5i63cn4X8T8N1sZ2mGkJD5lNRnBM4PZgI_zvzbr-cgUDVDqtaQTYon0UJ-k2YEGfKfDWAwz9BnfBPkKvSHAgfU5O-1S8eY4mNjHAQConK47tnE7ksezmOrLL0_DR1Mm0P", "fulfills": null, "owners_before": [ "4K9sWUMFwTgaDGPfdynrbxWqWS6sWmKbZoTjxLtVUibD" ] } ], - "metadata": { - "sequence": 0 - }, + "metadata": "QmZs4UHLHCUGLQr6rzbtJTjT8Sf5pw6FNuaRZ5pzguk5FV", "operation": "CREATE", "outputs": [ { diff --git a/docs/root/source/connecting/http-samples/index-response.http b/docs/root/source/connecting/http-samples/index-response.http index e1cca43..55bea78 100644 --- a/docs/root/source/connecting/http-samples/index-response.http +++ b/docs/root/source/connecting/http-samples/index-response.http @@ -6,7 +6,7 @@ Content-Type: application/json "v1": { "assets": "/api/v1/assets/", "blocks": "/api/v1/blocks/", - "docs": "https://docs.planetmint.io/projects/server/en/v1.0.1/http-client-server-api.html", + "docs": "https://docs.planetmint.io/projects/server/en/v1.2.2/http-client-server-api.html", "metadata": "/api/v1/metadata/", "outputs": "/api/v1/outputs/", "streamedblocks": "ws://localhost:9985/api/v1/streams/valid_blocks", @@ -15,7 +15,7 @@ Content-Type: application/json "validators": "/api/v1/validators" } }, - "docs": "https://docs.planetmint.io/projects/server/en/v1.0.1/", + "docs": "https://docs.planetmint.io/projects/server/en/v1.2.2/", "software": "Planetmint", - "version": "1.0.1" + "version": "1.2.2" } diff --git a/docs/root/source/connecting/http-samples/post-tx-request.http b/docs/root/source/connecting/http-samples/post-tx-request.http index 8ab0710..86d7688 100644 --- a/docs/root/source/connecting/http-samples/post-tx-request.http +++ b/docs/root/source/connecting/http-samples/post-tx-request.http @@ -4,23 +4,19 @@ Content-Type: application/json { "asset": { - "data": { - "msg": "Hello Planetmint!" - } + "data": "QmQP5C3PmhH9oB84n7YqSY4WVqmYatdoo1BdwhH4zmcwqM" }, - "id": "6438c733f53dff60bdeded80e8c95126dd3a7ce8c1ee5d5591d030e61cde35d2", + "id": "e4ebc02324e10925226bf2143363c1a28481ee38f70a9245a5a76df5f4380a7a", "inputs": [ { - "fulfillment": "pGSAIDE5i63cn4X8T8N1sZ2mGkJD5lNRnBM4PZgI_zvzbr-cgUBcdRj6EnG3MPl47m3XPd1HNfe7q3WL4T6MewNNnat33UvzVnPHo_vossv57M7L064VwrYMLGp097H7IeHpDngK", + "fulfillment": "pGSAIDE5i63cn4X8T8N1sZ2mGkJD5lNRnBM4PZgI_zvzbr-cgUDVDqtaQTYon0UJ-k2YEGfKfDWAwz9BnfBPkKvSHAgfU5O-1S8eY4mNjHAQConK47tnE7ksezmOrLL0_DR1Mm0P", "fulfills": null, "owners_before": [ "4K9sWUMFwTgaDGPfdynrbxWqWS6sWmKbZoTjxLtVUibD" ] } ], - "metadata": { - "sequence": 0 - }, + "metadata": "QmZs4UHLHCUGLQr6rzbtJTjT8Sf5pw6FNuaRZ5pzguk5FV", "operation": "CREATE", "outputs": [ { diff --git a/docs/root/source/connecting/http-samples/post-tx-response.http b/docs/root/source/connecting/http-samples/post-tx-response.http index 653014e..75639d2 100644 --- a/docs/root/source/connecting/http-samples/post-tx-response.http +++ b/docs/root/source/connecting/http-samples/post-tx-response.http @@ -3,23 +3,19 @@ Content-Type: application/json { "asset": { - "data": { - "msg": "Hello Planetmint!" - } + "data": "QmQP5C3PmhH9oB84n7YqSY4WVqmYatdoo1BdwhH4zmcwqM" }, - "id": "6438c733f53dff60bdeded80e8c95126dd3a7ce8c1ee5d5591d030e61cde35d2", + "id": "e4ebc02324e10925226bf2143363c1a28481ee38f70a9245a5a76df5f4380a7a", "inputs": [ { - "fulfillment": "pGSAIDE5i63cn4X8T8N1sZ2mGkJD5lNRnBM4PZgI_zvzbr-cgUBcdRj6EnG3MPl47m3XPd1HNfe7q3WL4T6MewNNnat33UvzVnPHo_vossv57M7L064VwrYMLGp097H7IeHpDngK", + "fulfillment": "pGSAIDE5i63cn4X8T8N1sZ2mGkJD5lNRnBM4PZgI_zvzbr-cgUDVDqtaQTYon0UJ-k2YEGfKfDWAwz9BnfBPkKvSHAgfU5O-1S8eY4mNjHAQConK47tnE7ksezmOrLL0_DR1Mm0P", "fulfills": null, "owners_before": [ "4K9sWUMFwTgaDGPfdynrbxWqWS6sWmKbZoTjxLtVUibD" ] } ], - "metadata": { - "sequence": 0 - }, + "metadata": "QmZs4UHLHCUGLQr6rzbtJTjT8Sf5pw6FNuaRZ5pzguk5FV", "operation": "CREATE", "outputs": [ { diff --git a/docs/root/source/introduction/quickstart.md b/docs/root/source/introduction/quickstart.md index 5549856..729bfd6 100644 --- a/docs/root/source/introduction/quickstart.md +++ b/docs/root/source/introduction/quickstart.md @@ -43,7 +43,11 @@ $ python notarize.py # Install Planetmint ## Local Node Planemtint is a Tendermint applicatoin with an attached database. +<<<<<<< HEAD A basic installation installs the database, Tendermint and therafter Planetmint. +======= +A basic installation installs the database, Tenermint and therafter Planetmint. +>>>>>>> planetmint-tarantool Planetmint currently supports Tarantool and MongoDB database. The installation is as follows: ``` diff --git a/integration/python/src/test_zenroom.py b/integration/python/src/test_zenroom.py index f38db29..6591314 100644 --- a/integration/python/src/test_zenroom.py +++ b/integration/python/src/test_zenroom.py @@ -3,7 +3,6 @@ import base58 from hashlib import sha3_256 from cryptoconditions.types.zenroom import ZenroomSha256 from planetmint_driver.crypto import generate_keypair - from .helper.hosts import Hosts from zenroom import zencode_exec import time @@ -72,7 +71,7 @@ def test_zenroom_signing( "output": ["ok"], "policies": {}, } - + metadata = {"result": {"output": ["ok"]}} token_creation_tx = { "operation": "CREATE", "asset": {"data": {"test": "my asset"}}, diff --git a/planetmint/backend/__init__.py b/planetmint/backend/__init__.py index 1468dc7..4f3e4fd 100644 --- a/planetmint/backend/__init__.py +++ b/planetmint/backend/__init__.py @@ -13,4 +13,4 @@ configuration or the ``PLANETMINT_DATABASE_BACKEND`` environment variable. # Include the backend interfaces from planetmint.backend import schema, query, convert # noqa -from planetmint.backend.connection import connect, Connection +from planetmint.backend.connection import Connection diff --git a/planetmint/backend/connection.py b/planetmint/backend/connection.py index 57e5d35..a99ed25 100644 --- a/planetmint/backend/connection.py +++ b/planetmint/backend/connection.py @@ -20,93 +20,43 @@ BACKENDS = { logger = logging.getLogger(__name__) - -def connect( - host: str = None, port: int = None, login: str = None, password: str = None, backend: str = None, **kwargs -): - try: - backend = backend - if not backend and kwargs and kwargs.get("backend"): - backend = kwargs["backend"] - - if backend and backend != Config().get()["database"]["backend"]: - Config().init_config(backend) - else: - backend = Config().get()["database"]["backend"] - except KeyError: - logger.info("Backend {} not supported".format(backend)) - raise ConfigurationError - - host = host or Config().get()["database"]["host"] if not kwargs.get("host") else kwargs["host"] - port = port or Config().get()["database"]["port"] if not kwargs.get("port") else kwargs["port"] - login = login or Config().get()["database"]["login"] if not kwargs.get("login") else kwargs["login"] - password = password or Config().get()["database"]["password"] - try: - if backend == "tarantool_db": - modulepath, _, class_name = BACKENDS[backend].rpartition(".") - Class = getattr(import_module(modulepath), class_name) - return Class(host=host, port=port, user=login, password=password, kwargs=kwargs) - elif backend == "localmongodb": - modulepath, _, class_name = BACKENDS[backend].rpartition(".") - Class = getattr(import_module(modulepath), class_name) - dbname = _kwargs_parser(key="name", kwargs=kwargs) or Config().get()["database"]["name"] - replicaset = _kwargs_parser(key="replicaset", kwargs=kwargs) or Config().get()["database"]["replicaset"] - ssl = _kwargs_parser(key="ssl", kwargs=kwargs) or Config().get()["database"]["ssl"] - login = ( - login or Config().get()["database"]["login"] - if _kwargs_parser(key="login", kwargs=kwargs) is None - else _kwargs_parser(key="login", kwargs=kwargs) # noqa: E501 - ) - password = ( - password or Config().get()["database"]["password"] - if _kwargs_parser(key="password", kwargs=kwargs) is None - else _kwargs_parser(key="password", kwargs=kwargs) # noqa: E501 - ) - ca_cert = _kwargs_parser(key="ca_cert", kwargs=kwargs) or Config().get()["database"]["ca_cert"] - certfile = _kwargs_parser(key="certfile", kwargs=kwargs) or Config().get()["database"]["certfile"] - keyfile = _kwargs_parser(key="keyfile", kwargs=kwargs) or Config().get()["database"]["keyfile"] - keyfile_passphrase = ( - _kwargs_parser(key="keyfile_passphrase", kwargs=kwargs) - or Config().get()["database"]["keyfile_passphrase"] - ) - crlfile = _kwargs_parser(key="crlfile", kwargs=kwargs) or Config().get()["database"]["crlfile"] - max_tries = _kwargs_parser(key="max_tries", kwargs=kwargs) - connection_timeout = _kwargs_parser(key="connection_timeout", kwargs=kwargs) - - return Class( - host=host, - port=port, - dbname=dbname, - max_tries=max_tries, - connection_timeout=connection_timeout, - replicaset=replicaset, - ssl=ssl, - login=login, - password=password, - ca_cert=ca_cert, - certfile=certfile, - keyfile=keyfile, - keyfile_passphrase=keyfile_passphrase, - crlfile=crlfile, - ) - except tarantool.error.NetworkError as network_err: - print(f"Host {host}:{port} can't be reached.\n{network_err}") - raise network_err - - def _kwargs_parser(key, kwargs): if kwargs.get(key): return kwargs[key] return None +class DBSingleton(type): + _instances = {} -class Connection: + def __call__(cls, *args, **kwargs): + if cls not in cls._instances: + try: + backend = kwargs.get("backend") if kwargs and kwargs.get("backend") else None + if backend is not None and backend != Config().get()["database"]["backend"]: + Config().init_config(backend) + else: + backend = Config().get()["database"]["backend"] + except KeyError: + logger.info("Backend {} not supported".format(backend)) + raise ConfigurationError + modulepath, _, class_name = BACKENDS[backend].rpartition('.') + Class = getattr(import_module(modulepath), class_name) + cls._instances[cls] = super(DBSingleton, Class).__call__(*args, **kwargs) + return cls._instances[cls] + +class Connection(metaclass=DBSingleton): + + def __init__(self) -> None: + pass + +class DBConnection(metaclass=DBSingleton): """Connection class interface. All backend implementations should provide a connection class that inherits from and implements this class. """ - def __init__(self, host=None, port=None, dbname=None, connection_timeout=None, max_tries=None, **kwargs): + def __init__(self, host: str =None, port: int = None, login: str = None, password: str = None, backend: str = None, + connection_timeout: int = None, max_tries: int = None, **kwargs): """Create a new :class:`~.Connection` instance. Args: host (str): the host to connect to. @@ -120,24 +70,16 @@ class Connection: **kwargs: arbitrary keyword arguments provided by the configuration's ``database`` settings """ + dbconf = Config().get()['database'] - dbconf = Config().get()["database"] + self.host = host or dbconf["host"] if not kwargs.get("host") else kwargs["host"] + self.port = port or dbconf['port'] if not kwargs.get("port") else kwargs["port"] + self.login = login or dbconf['login'] if not kwargs.get("login") else kwargs["login"] + self.password = password or dbconf['password'] if not kwargs.get("password") else kwargs["password"] - self.host = host or dbconf["host"] - self.port = port or dbconf["port"] - self.dbname = dbname or dbconf["name"] - self.connection_timeout = ( - connection_timeout if connection_timeout is not None else dbconf["connection_timeout"] - ) - self.max_tries = max_tries if max_tries is not None else dbconf["max_tries"] + self.connection_timeout = connection_timeout if connection_timeout is not None else Config().get()["database"] + self.max_tries = max_tries if max_tries is not None else dbconf['max_tries'] self.max_tries_counter = range(self.max_tries) if self.max_tries != 0 else repeat(0) - self._conn = None - - @property - def conn(self): - if self._conn is None: - self.connect() - return self._conn def run(self, query): """Run a query. @@ -160,23 +102,12 @@ class Connection: :exc:`~ConnectionError`: If the connection to the database fails. """ + raise NotImplementedError() - attempt = 0 - for i in self.max_tries_counter: - attempt += 1 - try: - self._conn = self._connect() - except ConnectionError as exc: - logger.warning( - "Attempt %s/%s. Connection to %s:%s failed after %sms.", - attempt, - self.max_tries if self.max_tries != 0 else "∞", - self.host, - self.port, - self.connection_timeout, - ) - if attempt == self.max_tries: - logger.critical("Cannot connect to the Database. Giving up.") - raise ConnectionError() from exc - else: - break + def close(self): + """Try to close connection to the database. + Raises: + :exc:`~ConnectionError`: If the connection to the database + fails. + """ + raise NotImplementedError() diff --git a/planetmint/backend/localmongodb/connection.py b/planetmint/backend/localmongodb/connection.py index 1851f2e..2506bb5 100644 --- a/planetmint/backend/localmongodb/connection.py +++ b/planetmint/backend/localmongodb/connection.py @@ -8,28 +8,18 @@ from ssl import CERT_REQUIRED import pymongo from planetmint.config import Config -from planetmint.backend.exceptions import DuplicateKeyError, OperationError, ConnectionError +from planetmint.backend.exceptions import (DuplicateKeyError, + OperationError, + ConnectionError) from planetmint.transactions.common.exceptions import ConfigurationError from planetmint.utils import Lazy -from planetmint.backend.connection import Connection +from planetmint.backend.connection import DBConnection, _kwargs_parser logger = logging.getLogger(__name__) +class LocalMongoDBConnection(DBConnection): -class LocalMongoDBConnection(Connection): - def __init__( - self, - replicaset=None, - ssl=None, - login=None, - password=None, - ca_cert=None, - certfile=None, - keyfile=None, - keyfile_passphrase=None, - crlfile=None, - **kwargs, - ): + def __init__(self, host: str =None, port: int = None, login: str = None, password: str = None, **kwargs): """Create a new Connection instance. Args: @@ -39,16 +29,24 @@ class LocalMongoDBConnection(Connection): configuration's ``database`` settings """ - super().__init__(**kwargs) - self.replicaset = replicaset or Config().get()["database"]["replicaset"] - self.ssl = ssl if ssl is not None else Config().get()["database"]["ssl"] - self.login = login or Config().get()["database"]["login"] - self.password = password or Config().get()["database"]["password"] - self.ca_cert = ca_cert or Config().get()["database"]["ca_cert"] - self.certfile = certfile or Config().get()["database"]["certfile"] - self.keyfile = keyfile or Config().get()["database"]["keyfile"] - self.keyfile_passphrase = keyfile_passphrase or Config().get()["database"]["keyfile_passphrase"] - self.crlfile = crlfile or Config().get()["database"]["crlfile"] + super().__init__(host=host, port=port, login=login, password=password, **kwargs) + + dbconf = Config().get()['database'] + self.dbname = _kwargs_parser(key="name", kwargs=kwargs) or dbconf['name'] + self.replicaset = _kwargs_parser(key="replicaset", kwargs=kwargs) or dbconf['replicaset'] + self.ssl = _kwargs_parser(key="ssl", kwargs=kwargs) or dbconf['ssl'] + + self.ca_cert = _kwargs_parser(key="ca_cert", kwargs=kwargs) or dbconf['ca_cert'] + self.certfile = _kwargs_parser(key="certfile", kwargs=kwargs) or dbconf['certfile'] + self.keyfile = _kwargs_parser(key="keyfile", kwargs=kwargs) or dbconf['keyfile'] + self.keyfile_passphrase = _kwargs_parser(key="keyfile_passphrase", kwargs=kwargs) or dbconf[ + 'keyfile_passphrase'] + self.crlfile = _kwargs_parser(key="crlfile", kwargs=kwargs) or dbconf['crlfile'] + self.max_tries = _kwargs_parser(key="max_tries", kwargs=kwargs) + self.connection_timeout = _kwargs_parser(key="connection_timeout", kwargs=kwargs) + self.__conn = None + self.connect() + if not self.ssl: self.ssl = False if not self.keyfile_passphrase: @@ -56,7 +54,7 @@ class LocalMongoDBConnection(Connection): @property def db(self): - return self.conn[self.dbname] + return self.connect()[self.dbname] def query(self): return Lazy() @@ -72,10 +70,11 @@ class LocalMongoDBConnection(Connection): def run(self, query): try: try: - return query.run(self.conn) + return query.run(self.connect()) except pymongo.errors.AutoReconnect: - logger.warning("Lost connection to the database, " "retrying query.") - return query.run(self.conn) + logger.warning('Lost connection to the database, ' + 'retrying query.') + return query.run(self.connect()) except pymongo.errors.AutoReconnect as exc: raise ConnectionError from exc except pymongo.errors.DuplicateKeyError as exc: @@ -84,7 +83,7 @@ class LocalMongoDBConnection(Connection): print(f"DETAILS: {exc.details}") raise OperationError from exc - def _connect(self): + def connect(self): """Try to connect to the database. Raises: @@ -95,7 +94,8 @@ class LocalMongoDBConnection(Connection): :exc:`~ConfigurationError`: If there is a ConfigurationError while connecting to the database. """ - + if self.__conn: + return self._conn try: # FYI: the connection process might raise a # `ServerSelectionTimeoutError`, that is a subclass of @@ -130,16 +130,25 @@ class LocalMongoDBConnection(Connection): **MONGO_OPTS, ) if self.login is not None: - client[self.dbname].authenticate(self.login, mechanism="MONGODB-X509") - + client[self.dbname].authenticate(self.login, + mechanism='MONGODB-X509') + self.__conn = client return client - except (pymongo.errors.ConnectionFailure, pymongo.errors.OperationFailure) as exc: - logger.info("Exception in _connect(): {}".format(exc)) + except (pymongo.errors.ConnectionFailure, + pymongo.errors.OperationFailure) as exc: + logger.info('Exception in connect(): {}'.format(exc)) raise ConnectionError(str(exc)) from exc except pymongo.errors.ConfigurationError as exc: raise ConfigurationError from exc + def close(self): + try: + self.__conn.close() + self.__conn = None + except Exception as exc: + logger.info('Exception in planetmint.backend.localmongodb.close(): {}'.format(exc)) + raise ConnectionError(str(exc)) from exc MONGO_OPTS = { "socketTimeoutMS": 20000, diff --git a/planetmint/backend/localmongodb/convert.py b/planetmint/backend/localmongodb/convert.py index 5e3aa87..d8121fb 100644 --- a/planetmint/backend/localmongodb/convert.py +++ b/planetmint/backend/localmongodb/convert.py @@ -14,7 +14,7 @@ register_query = module_dispatch_registrar(convert) @register_query(LocalMongoDBConnection) def prepare_asset(connection, transaction_type, transaction_id, filter_operation, asset): - if transaction_type in filter_operation: + if transaction_type not in filter_operation: asset["id"] = transaction_id return asset diff --git a/planetmint/backend/localmongodb/query.py b/planetmint/backend/localmongodb/query.py index 355fc1e..5ee887b 100644 --- a/planetmint/backend/localmongodb/query.py +++ b/planetmint/backend/localmongodb/query.py @@ -1,5 +1,4 @@ from functools import singledispatch - # Copyright © 2020 Interplanetary Database Association e.V., # Planetmint and IPDB software contributors. # SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0) diff --git a/planetmint/backend/schema.py b/planetmint/backend/schema.py index 9d10e57..984af33 100644 --- a/planetmint/backend/schema.py +++ b/planetmint/backend/schema.py @@ -9,7 +9,7 @@ from functools import singledispatch import logging from planetmint.config import Config -from planetmint.backend.connection import connect +from planetmint.backend.connection import Connection from planetmint.transactions.common.exceptions import ValidationError from planetmint.transactions.common.utils import ( validate_all_values_for_key_in_obj, @@ -134,8 +134,9 @@ def init_database(connection=None, dbname=None): configuration. """ - connection = connection or connect() - dbname = dbname or Config().get()["database"]["name"] + connection = connection or Connection() + print("=========================================", connection.__class__, "=========================================================") + dbname = dbname or Config().get()['database']['name'] create_database(connection, dbname) create_tables(connection, dbname) diff --git a/planetmint/backend/tarantool/connection.py b/planetmint/backend/tarantool/connection.py index cc6ba8d..b3644e5 100644 --- a/planetmint/backend/tarantool/connection.py +++ b/planetmint/backend/tarantool/connection.py @@ -7,29 +7,30 @@ import logging import tarantool from planetmint.config import Config -from planetmint.transactions.common.exceptions import ConfigurationError +from planetmint.transactions.common.exceptions import ConfigurationError, ConnectionError from planetmint.utils import Lazy -from planetmint.backend.connection import Connection +from planetmint.backend.connection import DBConnection logger = logging.getLogger(__name__) -class TarantoolDBConnection(Connection): +class TarantoolDBConnection(DBConnection): def __init__( self, host: str = "localhost", port: int = 3303, - user: str = None, + login: str = None, password: str = None, **kwargs, ): try: - super().__init__(**kwargs) - self.host = host - self.port = port - # TODO add user support later on - self.init_path = Config().get()["database"]["init_config"]["absolute_path"] - self.drop_path = Config().get()["database"]["drop_config"]["absolute_path"] + super().__init__(host=host, port=port, login=login, password=password, **kwargs) + + dbconf = Config().get()["database"] + self.init_path = dbconf["init_config"]["absolute_path"] + self.drop_path = dbconf["drop_config"]["absolute_path"] + self.__conn = None + self.connect() self.SPACE_NAMES = [ "abci_chains", "assets", @@ -46,7 +47,7 @@ class TarantoolDBConnection(Connection): ] except tarantool.error.NetworkError as network_err: logger.info("Host cant be reached") - raise network_err + raise ConnectionError except ConfigurationError: logger.info("Exception in _connect(): {}") raise ConfigurationError @@ -60,27 +61,40 @@ class TarantoolDBConnection(Connection): f.close() return "".join(execute).encode() - def _connect(self): - return tarantool.connect(host=self.host, port=self.port) + def connect(self): + if not self.__conn: + self.__conn = tarantool.connect(host=self.host, port=self.port) + return self.__conn + + def close(self): + try: + self.__conn.close() + self.__conn = None + except Exception as exc: + logger.info('Exception in planetmint.backend.tarantool.close(): {}'.format(exc)) + raise ConnectionError(str(exc)) from exc def get_space(self, space_name: str): - return self.conn.space(space_name) + return self.get_connection().space(space_name) def space(self, space_name: str): return self.query().space(space_name) def run(self, query, only_data=True): try: - return query.run(self.conn).data if only_data else query.run(self.conn) + return query.run(self.get_connection()).data if only_data else query.run(self.get_connection()) except tarantool.error.OperationalError as op_error: raise op_error except tarantool.error.NetworkError as net_error: raise net_error def get_connection(self): - return self.conn + if not self.__conn: + self.connect() + return self.__conn def drop_database(self): + self.close() db_config = Config().get()["database"] cmd_resp = self.run_command(command=self.drop_path, config=db_config) # noqa: F841 diff --git a/planetmint/backend/tarantool/convert.py b/planetmint/backend/tarantool/convert.py index 15ea5ef..7fb90a2 100644 --- a/planetmint/backend/tarantool/convert.py +++ b/planetmint/backend/tarantool/convert.py @@ -16,7 +16,7 @@ register_query = module_dispatch_registrar(convert) def prepare_asset(connection, transaction_type, transaction_id, filter_operation, asset): asset_id = transaction_id if transaction_type not in filter_operation: - asset_id = asset["id"] + asset_id = asset['id'] return tuple([asset, transaction_id, asset_id]) diff --git a/planetmint/commands/planetmint.py b/planetmint/commands/planetmint.py index f2928e8..7eae2a3 100644 --- a/planetmint/commands/planetmint.py +++ b/planetmint/commands/planetmint.py @@ -256,9 +256,9 @@ def run_drop(args): if response != "y": return - from planetmint.backend.connection import connect + from planetmint.backend.connection import Connection - conn = connect() + conn = Connection() try: schema.drop_database(conn) except DatabaseDoesNotExist: diff --git a/planetmint/config.py b/planetmint/config.py index f9c89e2..87e6160 100644 --- a/planetmint/config.py +++ b/planetmint/config.py @@ -1,7 +1,6 @@ import copy import logging import os - # from planetmint.log import DEFAULT_LOGGING_CONFIG as log_config from planetmint.version import __version__ # noqa diff --git a/planetmint/lib.py b/planetmint/lib.py index 3c37124..c13af74 100644 --- a/planetmint/lib.py +++ b/planetmint/lib.py @@ -10,6 +10,7 @@ MongoDB. import logging from collections import namedtuple from uuid import uuid4 +from planetmint.backend.connection import Connection import rapidjson @@ -73,7 +74,7 @@ class Planetmint(object): self.validation = config_utils.load_validation_plugin(validationPlugin) else: self.validation = BaseValidationRules - self.connection = connection if connection is not None else planetmint.backend.connect() + self.connection = connection if connection is not None else Connection() def post_transaction(self, transaction, mode): """Submit a valid transaction to the mempool.""" diff --git a/planetmint/log.py b/planetmint/log.py index 31bd150..c826526 100644 --- a/planetmint/log.py +++ b/planetmint/log.py @@ -11,7 +11,6 @@ from logging.config import dictConfig as set_logging_config from planetmint.config import Config, DEFAULT_LOGGING_CONFIG import os - def _normalize_log_level(level): try: return level.upper() diff --git a/planetmint/transactions/common/exceptions.py b/planetmint/transactions/common/exceptions.py index ed0c307..b0d7e66 100644 --- a/planetmint/transactions/common/exceptions.py +++ b/planetmint/transactions/common/exceptions.py @@ -10,6 +10,9 @@ from planetmint.exceptions import BigchainDBError class ConfigurationError(BigchainDBError): """Raised when there is a problem with server configuration""" + +class ConnectionError(BigchainDBError): + """Raised when there is a problem with server connection""" class DatabaseDoesNotExist(BigchainDBError): diff --git a/planetmint/transactions/common/transaction.py b/planetmint/transactions/common/transaction.py index 33f504c..f17b454 100644 --- a/planetmint/transactions/common/transaction.py +++ b/planetmint/transactions/common/transaction.py @@ -904,8 +904,12 @@ class Transaction(object): if asset_id != self.asset["id"]: raise AssetIdMismatch(("The asset id of the input does not" " match the asset id of the" " transaction")) - input_amount = sum([input_condition.amount for input_condition in input_conditions]) - output_amount = sum([output_condition.amount for output_condition in self.outputs]) + input_amount = sum( + [input_condition.amount for input_condition in input_conditions] + ) + output_amount = sum( + [output_condition.amount for output_condition in self.outputs] + ) if output_amount != input_amount: raise AmountError( diff --git a/planetmint/version.py b/planetmint/version.py index 2887e47..f227611 100644 --- a/planetmint/version.py +++ b/planetmint/version.py @@ -3,7 +3,7 @@ # SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0) # Code is Apache-2.0 and docs are CC-BY-4.0 -__version__ = "1.2.1" +__version__ = "1.2.2" __short_version__ = "1.2" # Supported Tendermint versions diff --git a/setup.py b/setup.py index 87cd566..5225bc2 100644 --- a/setup.py +++ b/setup.py @@ -89,7 +89,15 @@ docs_require = [ check_setuptools_features() -dev_require = ["ipdb", "ipython", "watchdog", "logging_tree", "pre-commit", "twine", "ptvsd"] +dev_require = [ + "ipdb", + "ipython", + "watchdog", + "logging_tree", + "pre-commit", + "twine", + "ptvsd" +] tests_require = [ "coverage", diff --git a/tests/backend/tarantool/conftest.py b/tests/backend/tarantool/conftest.py index 83cad05..ac4a7e1 100644 --- a/tests/backend/tarantool/conftest.py +++ b/tests/backend/tarantool/conftest.py @@ -1,5 +1,5 @@ import pytest -from planetmint.backend.connection import connect +from planetmint.backend.connection import Connection # @@ -27,5 +27,5 @@ from planetmint.backend.connection import connect @pytest.fixture def db_conn(): - conn = connect() + conn = Connection() return conn diff --git a/tests/backend/tarantool/test_queries.py b/tests/backend/tarantool/test_queries.py index 104fa94..b801a73 100644 --- a/tests/backend/tarantool/test_queries.py +++ b/tests/backend/tarantool/test_queries.py @@ -16,7 +16,6 @@ pytestmark = pytest.mark.bdb def test_get_txids_filtered(signed_create_tx, signed_transfer_tx, db_conn): from planetmint.backend.tarantool import query - # create and insert two blocks, one for the create and one for the # transfer transaction create_tx_dict = signed_create_tx.to_dict() diff --git a/tests/backend/test_connection.py b/tests/backend/test_connection.py index 471b42c..4629ed0 100644 --- a/tests/backend/test_connection.py +++ b/tests/backend/test_connection.py @@ -7,16 +7,12 @@ import pytest def test_get_connection_raises_a_configuration_error(monkeypatch): - from planetmint.transactions.common.exceptions import ConfigurationError - from planetmint.backend.connection import connect - - with pytest.raises(ConfigurationError): - connect("localhost", "1337", "mydb", "password", "msaccess") - - with pytest.raises(ConfigurationError): - # We need to force a misconfiguration here - monkeypatch.setattr( - "planetmint.backend.connection.BACKENDS", {"catsandra": "planetmint.backend.meowmeow.Catsandra"} - ) - - connect("localhost", "1337", "mydb", "password", "catsandra") + from planetmint.transactions.common.exceptions import ConfigurationError, ConnectionError + from planetmint.backend.connection import Connection + from planetmint.backend.localmongodb.connection import LocalMongoDBConnection + from planetmint.backend.tarantool.connection import TarantoolDBConnection + + with pytest.raises(ConnectionError): + LocalMongoDBConnection('localhost', '1337', 'mydb', 'password') + with pytest.raises(ConnectionError): + TarantoolDBConnection('localhost', '1337', 'mydb', 'password') diff --git a/tests/commands/conftest.py b/tests/commands/conftest.py index 2d72cd6..90f3144 100644 --- a/tests/commands/conftest.py +++ b/tests/commands/conftest.py @@ -8,7 +8,6 @@ import pytest from planetmint.config import Config - @pytest.fixture def mock_run_configure(monkeypatch): from planetmint.commands import planetmint diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index d77224a..703d3cb 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -14,13 +14,13 @@ import pytest from planetmint.config import Config from planetmint import ValidatorElection from planetmint.commands.planetmint import run_election_show +from planetmint.backend.connection import Connection from planetmint.transactions.types.elections.election import Election from planetmint.lib import Block from planetmint.transactions.types.elections.chain_migration_election import ChainMigrationElection from tests.utils import generate_election, generate_validators - def test_make_sure_we_dont_remove_any_command(): # thanks to: http://stackoverflow.com/a/18161115/597097 from planetmint.commands.planetmint import create_parser @@ -95,7 +95,6 @@ def test_bigchain_show_config(capsys): # dict returned is different that what is expected after run_show_config # and run_show_config updates the planetmint.config from planetmint.config import Config - _config = Config().get() sorted_config = json.dumps(_config, indent=4, sort_keys=True) print(f"_config : {sorted_config}") @@ -104,11 +103,10 @@ def test_bigchain_show_config(capsys): def test__run_init(mocker): - init_db_mock = mocker.patch("planetmint.backend.tarantool.connection.TarantoolDBConnection.init_database") + init_db_mock = mocker.patch( + 'planetmint.backend.tarantool.connection.TarantoolDBConnection.init_database') - from planetmint.backend.connection import connect - - conn = connect() + conn = Connection() conn.init_database() init_db_mock.assert_called_once_with() diff --git a/tests/conftest.py b/tests/conftest.py index 443a484..ba100e8 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -19,11 +19,10 @@ from ipld import marshal, multihash from collections import namedtuple from logging import getLogger from logging.config import dictConfig -from planetmint.backend.connection import connect +from planetmint.backend.connection import Connection from planetmint.backend.tarantool.connection import TarantoolDBConnection import pytest - # from pymongo import MongoClient from planetmint import ValidatorElection @@ -118,22 +117,22 @@ def _configure_planetmint(request): config_utils.set_config(config) -@pytest.fixture(scope="session") +@pytest.fixture(scope='session') def _setup_database(_configure_planetmint): # TODO Here is located setup database from planetmint.config import Config - print("Initializing test db") - dbname = Config().get()["database"]["name"] - conn = connect() + print('Initializing test db') + dbname = Config().get()['database']['name'] + conn = Connection() _drop_db(conn, dbname) schema.init_database(conn, dbname) - print("Finishing init database") + print('Finishing init database') yield - print("Deleting `{}` database".format(dbname)) - conn = connect() + print('Deleting `{}` database'.format(dbname)) + conn = Connection() _drop_db(conn, dbname) print("Finished deleting `{}`".format(dbname)) @@ -145,10 +144,9 @@ def _bdb(_setup_database, _configure_planetmint): from planetmint.transactions.common.transaction import Transaction from .utils import flush_db from planetmint.config import Config - - conn = connect() + conn = Connection() yield - dbname = Config().get()["database"]["name"] + dbname = Config().get()['database']['name'] flush_db(conn, dbname) to_dict.cache_clear() @@ -252,7 +250,6 @@ def abci_fixture(): return types_pb2 - @pytest.fixture def b(): from planetmint import Planetmint @@ -393,7 +390,7 @@ def db_name(db_config): @pytest.fixture def db_conn(): - return connect() + return Connection() @pytest.fixture @@ -550,7 +547,6 @@ def tarantool_client(db_context): # TODO Here add TarantoolConnectionClass # # - @pytest.fixture def utxo_collection(tarantool_client, _setup_database): return tarantool_client.get_space("utxos") @@ -568,7 +564,6 @@ def dummy_unspent_outputs(): @pytest.fixture def utxoset(dummy_unspent_outputs, utxo_collection): from json import dumps - num_rows_before_operation = utxo_collection.select().rowcount for utxo in dummy_unspent_outputs: res = utxo_collection.insert((utxo["transaction_id"], utxo["output_index"], dumps(utxo))) @@ -624,7 +619,6 @@ def node_keys(): "PecJ58SaNRsWJZodDmqjpCWqG6btdwXFHLyE40RYlYM=": "uz8bYgoL4rHErWT1gjjrnA+W7bgD/uDQWSRKDmC8otc95wnnxJo1GxYlmh0OaqOkJaobpu13BcUcvITjRFiVgw==", } - @pytest.fixture def priv_validator_path(node_keys): (public_key, private_key) = list(node_keys.items())[0] diff --git a/tests/tendermint/test_fastquery.py b/tests/tendermint/test_fastquery.py index d37d0a5..be1f2d2 100644 --- a/tests/tendermint/test_fastquery.py +++ b/tests/tendermint/test_fastquery.py @@ -91,7 +91,7 @@ def test_filter_unspent_outputs(b, user_pk, user_sk): def test_outputs_query_key_order(b, user_pk, user_sk, user2_pk, user2_sk): from planetmint import backend - from planetmint.backend.connection import connect + from planetmint.backend.connection import Connection from planetmint.backend import query tx1 = Create.generate([user_pk], [([user_pk], 3), ([user_pk], 2), ([user_pk], 1)]).sign([user_sk]) @@ -116,7 +116,11 @@ def test_outputs_query_key_order(b, user_pk, user_sk, user2_pk, user2_sk): assert len(outputs) == 1 # clean the transaction, metdata and asset collection - connection = connect() + # conn = connect() + connection = Connection() + # conn.run(conn.collection('transactions').delete_many({})) + # conn.run(conn.collection('metadata').delete_many({})) + # conn.run(conn.collection('assets').delete_many({})) query.delete_transactions(connection, txn_ids=[tx1.id, tx2.id]) b.store_bulk_transactions([tx1]) diff --git a/tests/tendermint/test_lib.py b/tests/tendermint/test_lib.py index c7e7077..d08d5b8 100644 --- a/tests/tendermint/test_lib.py +++ b/tests/tendermint/test_lib.py @@ -290,7 +290,6 @@ def test_delete_zero_unspent_outputs(b, utxoset): @pytest.mark.bdb def test_delete_one_unspent_outputs(b, utxoset): from planetmint.backend.tarantool.connection import TarantoolDBConnection - unspent_outputs, utxo_collection = utxoset delete_res = b.delete_unspent_outputs(unspent_outputs[0]) if not isinstance(b.connection, TarantoolDBConnection): @@ -319,7 +318,6 @@ def test_delete_one_unspent_outputs(b, utxoset): @pytest.mark.bdb def test_delete_many_unspent_outputs(b, utxoset): from planetmint.backend.tarantool.connection import TarantoolDBConnection - unspent_outputs, utxo_collection = utxoset delete_res = b.delete_unspent_outputs(*unspent_outputs[::2]) if not isinstance(b.connection, TarantoolDBConnection): @@ -357,7 +355,6 @@ def test_store_zero_unspent_output(b, utxo_collection): @pytest.mark.bdb def test_store_one_unspent_output(b, unspent_output_1, utxo_collection): from planetmint.backend.tarantool.connection import TarantoolDBConnection - res = b.store_unspent_outputs(unspent_output_1) if not isinstance(b.connection, TarantoolDBConnection): assert res.acknowledged @@ -382,7 +379,6 @@ def test_store_one_unspent_output(b, unspent_output_1, utxo_collection): @pytest.mark.bdb def test_store_many_unspent_outputs(b, unspent_outputs, utxo_collection): from planetmint.backend.tarantool.connection import TarantoolDBConnection - res = b.store_unspent_outputs(*unspent_outputs) if not isinstance(b.connection, TarantoolDBConnection): assert res.acknowledged diff --git a/tests/test_core.py b/tests/test_core.py index f2b7cbc..e9337b2 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -18,6 +18,7 @@ from planetmint.transactions.types.elections.election import Election from planetmint.lib import Block from planetmint.transactions.types.elections.chain_migration_election import ChainMigrationElection from planetmint.upsert_validator.validator_election import ValidatorElection +from planetmint.backend.exceptions import ConnectionError from planetmint.upsert_validator.validator_utils import new_validator_set from planetmint.tendermint_utils import public_key_to_base64 from planetmint.version import __tm_supported_versions__ @@ -54,34 +55,25 @@ def config(request, monkeypatch): monkeypatch.setattr("planetmint.config", config) return config +def test_bigchain_class_initialization_with_parameters(): + from planetmint.backend.localmongodb.connection import LocalMongoDBConnection + from planetmint.transactions.common.exceptions import ConfigurationError + + init_db_kwargs = { + 'backend': 'localmongodb', + 'host': 'this_is_the_db_host', + 'port': 12345, + 'name': 'this_is_the_db_name', + } + with pytest.raises(ConfigurationError): + LocalMongoDBConnection(**init_db_kwargs) def test_bigchain_class_default_initialization(config): from planetmint import Planetmint from planetmint.validation import BaseValidationRules - planet = Planetmint() - assert planet.connection.host == config["database"]["host"] - assert planet.connection.port == config["database"]["port"] - assert planet.validation == BaseValidationRules - - -def test_bigchain_class_initialization_with_parameters(): - from planetmint import Planetmint - from planetmint.backend import connect - from planetmint.validation import BaseValidationRules - - init_db_kwargs = { - "backend": "localmongodb", - "host": "this_is_the_db_host", - "port": 12345, - "name": "this_is_the_db_name", - } - connection = connect(**init_db_kwargs) - planet = Planetmint(connection=connection) - assert planet.connection == connection - assert planet.connection.host == init_db_kwargs["host"] - assert planet.connection.port == init_db_kwargs["port"] - # assert planet.connection.name == init_db_kwargs['name'] + assert planet.connection.host == config['database']['host'] + assert planet.connection.port == config['database']['port'] assert planet.validation == BaseValidationRules diff --git a/tests/web/test_transactions.py b/tests/web/test_transactions.py index b2fd3e0..f70a631 100644 --- a/tests/web/test_transactions.py +++ b/tests/web/test_transactions.py @@ -348,7 +348,9 @@ def test_post_transfer_transaction_endpoint(client, user_pk, user_sk, posted_cre @pytest.mark.abci -def test_post_invalid_transfer_transaction_returns_400(client, user_pk, posted_create_tx): +def test_post_invalid_transfer_transaction_returns_400( + client, user_pk, posted_create_tx +): from planetmint.transactions.common.exceptions import InvalidSignature transfer_tx = Transfer.generate(posted_create_tx.to_inputs(), [([user_pk], 1)], asset_id=posted_create_tx.id)