diff --git a/.github/workflows/documenation.yml b/.github/workflows/documenation.yml deleted file mode 100644 index 4cda540..0000000 --- a/.github/workflows/documenation.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright © 2020 Interplanetary Database Association e.V., -# Planetmint and IPDB software contributors. -# SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0) -# Code is Apache-2.0 and docs are CC-BY-4.0 - -name: Documentation -on: [push, pull_request] - -jobs: - documentation: - runs-on: ubuntu-latest - - steps: - - name: Check out repository code - uses: actions/checkout@v3 - - - name: Setup python - uses: actions/setup-python@v4 - with: - python-version: 3.9 - - - name: Install tox - run: python -m pip install --upgrade tox tox-gh-actions - - - name: Install dependencies - run: pip install .'[dev]' - - - name: Run tox - run: tox -e docsroot - - - - - - \ No newline at end of file diff --git a/.gitignore b/.gitignore index 16cd16f..411bda4 100644 --- a/.gitignore +++ b/.gitignore @@ -53,7 +53,6 @@ pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ -.tox/ .coverage .coverage.* .cache diff --git a/CHANGELOG.md b/CHANGELOG.md index 469cc5a..900bdf3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,16 @@ For reference, the possible headings are: * **Known Issues** * **Notes** +## [2.0.0] - 2023-12-01 +* **Changed** changed tarantool db schema +* **Removed** removed text_search routes +* **Added** metadata / asset cid route for fetching transactions + +## [1.4.1] - 2022-21-12 +* **fixed** inconsistent cryptocondition keyring tag handling. Using cryptoconditions > 1.1.0 from now on. + +## [1.4.0] - 2022-12-12 +* **Added** added upgrade compatibility to older nodes to support v2.0 TX validity for nodes supporting v3.0 transactions (planetmint-transactions >= 0.4.1) ## [1.3.2] - 2022-28-11 * **Changed** new zenroom 2.3.1 support diff --git a/docker-compose.yml b/docker-compose.yml index e7646b7..746af3e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -41,7 +41,6 @@ services: - ./setup.py:/usr/src/app/setup.py - ./setup.cfg:/usr/src/app/setup.cfg - ./pytest.ini:/usr/src/app/pytest.ini - - ./tox.ini:/usr/src/app/tox.ini environment: PLANETMINT_DATABASE_BACKEND: tarantool_db PLANETMINT_DATABASE_HOST: tarantool diff --git a/docs/root/requirements.txt b/docs/root/requirements.txt index c048f4f..93e5e50 100644 --- a/docs/root/requirements.txt +++ b/docs/root/requirements.txt @@ -1,7 +1,7 @@ aafigure==0.6 alabaster==0.7.12 Babel==2.10.1 -certifi==2021.10.8 +certifi==2022.12.7 charset-normalizer==2.0.12 commonmark==0.9.1 docutils==0.17.1 diff --git a/docs/root/source/conf.py b/docs/root/source/conf.py index 8dc1e0e..c072717 100644 --- a/docs/root/source/conf.py +++ b/docs/root/source/conf.py @@ -54,13 +54,13 @@ import sphinx_rtd_theme extensions = [ "myst_parser", + "sphinx.ext.napoleon", "sphinx.ext.autosectionlabel", "sphinx.ext.autodoc", "sphinx.ext.intersphinx", "sphinx.ext.coverage", "sphinx.ext.viewcode", "sphinx.ext.todo", - "sphinx.ext.napoleon", "sphinxcontrib.httpdomain", "aafigure.sphinxext", #'sphinx_toolbox.collapse', 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 921c30b..fd32de7 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.3.1/http-client-server-api.html", + "docs": "https://docs.planetmint.io/projects/server/en/v1.4.1/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 200a822..7fe5e73 100644 --- a/docs/root/source/connecting/http-samples/get-block-response.http +++ b/docs/root/source/connecting/http-samples/get-block-response.http @@ -7,15 +7,13 @@ Content-Type: application/json { "assets": [ { - "data": { - "msg": "Hello Planetmint!" - } + "data": "QmQP5C3PmhH9oB84n7YqSY4WVqmYatdoo1BdwhH4zmcwqM" } ], - "id": "61e1312b80705e0dabb948c9d78dae7f62d64832abda822b13d89c4a7305d4ac", + "id": "0fdeb547670bbea980389df53cf5a91e60159339084c6b0b5cc0b5494a679530", "inputs": [ { - "fulfillment": "pGSAIDE5i63cn4X8T8N1sZ2mGkJD5lNRnBM4PZgI_zvzbr-cgUCWcUaLa2U-nkmZ6oYj14aeV6B4TJH2NvZ8k2ZTwcGiaiCGXDQT2dEPfMCFwM8lwSousafCu4c7EgVZ1GzUDjsN", + "fulfillment": "pGSAIDE5i63cn4X8T8N1sZ2mGkJD5lNRnBM4PZgI_zvzbr-cgUDklzRb5aUQz9slbaqSWap1AfC-cacTCN3CGtFy2LPK7JKEqKG2b0KQXnUcFksk_KH_v6ImFXHsclKSp1OJkIEI", "fulfills": null, "owners_before": [ "4K9sWUMFwTgaDGPfdynrbxWqWS6sWmKbZoTjxLtVUibD" @@ -39,7 +37,7 @@ Content-Type: application/json ] } ], - "version": "2.0" + "version": "3.0" } ] } 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 b3e8bd3..99dba30 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=61e1312b80705e0dabb948c9d78dae7f62d64832abda822b13d89c4a7305d4ac HTTP/1.1 +GET /api/v1/blocks?transaction_id=0fdeb547670bbea980389df53cf5a91e60159339084c6b0b5cc0b5494a679530 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 560bcbc..4fcbd0b 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=61e1312b80705e0dabb948c9d78dae7f62d64832abda822b13d89c4a7305d4ac HTTP/1.1 +GET /api/v1/transactions?operation=TRANSFER&asset_id=0fdeb547670bbea980389df53cf5a91e60159339084c6b0b5cc0b5494a679530 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 aac836b..9664858 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 @@ -4,16 +4,16 @@ Content-Type: application/json [{ "assets": [ { - "id": "61e1312b80705e0dabb948c9d78dae7f62d64832abda822b13d89c4a7305d4ac" + "id": "0fdeb547670bbea980389df53cf5a91e60159339084c6b0b5cc0b5494a679530" } ], - "id": "b6e1ab3d48bbbbb0e40b952e70ec5d439b2745e0ba0c44b4ee877657e9ac33f0", + "id": "8d11fe2bd91c4747a41e0c3dbe1400c511175be42f008d6cff92cbfa9e04f799", "inputs": [ { - "fulfillment": "pGSAIDE5i63cn4X8T8N1sZ2mGkJD5lNRnBM4PZgI_zvzbr-cgUA4BB4fxDXK3CQTbKpH5gTAN76NG-iopNuuDEfBbZ1Fl-ipNU46t8VCvK9ghm9Q53aFRW6DDiW5wcWXxY0sS4EJ", + "fulfillment": "pGSAIDE5i63cn4X8T8N1sZ2mGkJD5lNRnBM4PZgI_zvzbr-cgUCh-rpO-xqDm2fngjzxnKc39G16FpFMo0y50sHT7_uo1Itzvh4jsxnSGco2HjG6ZF-lSiGsASZ4uIIHuPM57yUI", "fulfills": { "output_index": 0, - "transaction_id": "61e1312b80705e0dabb948c9d78dae7f62d64832abda822b13d89c4a7305d4ac" + "transaction_id": "0fdeb547670bbea980389df53cf5a91e60159339084c6b0b5cc0b5494a679530" }, "owners_before": [ "4K9sWUMFwTgaDGPfdynrbxWqWS6sWmKbZoTjxLtVUibD" @@ -37,21 +37,21 @@ Content-Type: application/json ] } ], - "version": "2.0" + "version": "3.0" }, { "assets": [ { - "id": "61e1312b80705e0dabb948c9d78dae7f62d64832abda822b13d89c4a7305d4ac" + "id": "0fdeb547670bbea980389df53cf5a91e60159339084c6b0b5cc0b5494a679530" } ], - "id": "e43d3f93d90d22ef11c21607e3415bfcda4e0c7dd60412fbb55daf32978a3126", + "id": "45c929b66d1b10db6c3c3e6b1adddc0778b473fced4a1f403c2646b25f3fd983", "inputs": [ { - "fulfillment": "pGSAICw7Ul-c2lG6NFbHp3FbKRC7fivQcNGO7GS4wV3A-1QggUBjj_XTjB3yJdG8JMNKnkkHvcX_BTOkl-YacRD4yKqxUCeL-VTgbrLgi5a3gGxNJcTkZP1gF0nsby8cgV4xmOcB", + "fulfillment": "pGSAICw7Ul-c2lG6NFbHp3FbKRC7fivQcNGO7GS4wV3A-1QggUAc6OAQcXppDxCazw0UK2nwghctKNiZYDDsSOkAn0eQE8QjZ7GLzJpVb92oGXw_4FF7cLE0gg3nNxu7taQ8xakE", "fulfills": { "output_index": 0, - "transaction_id": "b6e1ab3d48bbbbb0e40b952e70ec5d439b2745e0ba0c44b4ee877657e9ac33f0" + "transaction_id": "8d11fe2bd91c4747a41e0c3dbe1400c511175be42f008d6cff92cbfa9e04f799" }, "owners_before": [ "3yfQPHeWAa1MxTX9Zf9176QqcpcnWcanVZZbaHb8B3h9" @@ -75,5 +75,5 @@ Content-Type: application/json ] } ], - "version": "2.0" + "version": "3.0" }] 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 1574cdd..1c397c5 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/61e1312b80705e0dabb948c9d78dae7f62d64832abda822b13d89c4a7305d4ac HTTP/1.1 +GET /api/v1/transactions/0fdeb547670bbea980389df53cf5a91e60159339084c6b0b5cc0b5494a679530 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 e4299ee..0183c41 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 @@ -4,15 +4,13 @@ Content-Type: application/json { "assets": [ { - "data": { - "msg": "Hello Planetmint!" - } + "data": "QmQP5C3PmhH9oB84n7YqSY4WVqmYatdoo1BdwhH4zmcwqM" } ], - "id": "61e1312b80705e0dabb948c9d78dae7f62d64832abda822b13d89c4a7305d4ac", + "id": "0fdeb547670bbea980389df53cf5a91e60159339084c6b0b5cc0b5494a679530", "inputs": [ { - "fulfillment": "pGSAIDE5i63cn4X8T8N1sZ2mGkJD5lNRnBM4PZgI_zvzbr-cgUCWcUaLa2U-nkmZ6oYj14aeV6B4TJH2NvZ8k2ZTwcGiaiCGXDQT2dEPfMCFwM8lwSousafCu4c7EgVZ1GzUDjsN", + "fulfillment": "pGSAIDE5i63cn4X8T8N1sZ2mGkJD5lNRnBM4PZgI_zvzbr-cgUDklzRb5aUQz9slbaqSWap1AfC-cacTCN3CGtFy2LPK7JKEqKG2b0KQXnUcFksk_KH_v6ImFXHsclKSp1OJkIEI", "fulfills": null, "owners_before": [ "4K9sWUMFwTgaDGPfdynrbxWqWS6sWmKbZoTjxLtVUibD" @@ -36,5 +34,5 @@ Content-Type: application/json ] } ], - "version": "2.0" + "version": "3.0" } diff --git a/docs/root/source/connecting/http-samples/index-response.http b/docs/root/source/connecting/http-samples/index-response.http index 67cf70c..4433e63 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.2.2/http-client-server-api.html", + "docs": "https://docs.planetmint.io/projects/server/en/v1.4.1/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.2.2/", + "docs": "https://docs.planetmint.io/projects/server/en/v1.4.1/", "software": "Planetmint", - "version": "1.3.1" + "version": "1.4.1" } 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 90868ee..7cf9015 100644 --- a/docs/root/source/connecting/http-samples/post-tx-request.http +++ b/docs/root/source/connecting/http-samples/post-tx-request.http @@ -5,15 +5,13 @@ Content-Type: application/json { "assets": [ { - "data": { - "msg": "Hello Planetmint!" - } + "data": "QmQP5C3PmhH9oB84n7YqSY4WVqmYatdoo1BdwhH4zmcwqM" } ], - "id": "61e1312b80705e0dabb948c9d78dae7f62d64832abda822b13d89c4a7305d4ac", + "id": "0fdeb547670bbea980389df53cf5a91e60159339084c6b0b5cc0b5494a679530", "inputs": [ { - "fulfillment": "pGSAIDE5i63cn4X8T8N1sZ2mGkJD5lNRnBM4PZgI_zvzbr-cgUCWcUaLa2U-nkmZ6oYj14aeV6B4TJH2NvZ8k2ZTwcGiaiCGXDQT2dEPfMCFwM8lwSousafCu4c7EgVZ1GzUDjsN", + "fulfillment": "pGSAIDE5i63cn4X8T8N1sZ2mGkJD5lNRnBM4PZgI_zvzbr-cgUDklzRb5aUQz9slbaqSWap1AfC-cacTCN3CGtFy2LPK7JKEqKG2b0KQXnUcFksk_KH_v6ImFXHsclKSp1OJkIEI", "fulfills": null, "owners_before": [ "4K9sWUMFwTgaDGPfdynrbxWqWS6sWmKbZoTjxLtVUibD" @@ -37,5 +35,5 @@ Content-Type: application/json ] } ], - "version": "2.0" + "version": "3.0" } 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 6404a2b..df0857b 100644 --- a/docs/root/source/connecting/http-samples/post-tx-response.http +++ b/docs/root/source/connecting/http-samples/post-tx-response.http @@ -4,15 +4,13 @@ Content-Type: application/json { "assets": [ { - "data": { - "msg": "Hello Planetmint!" - } + "data": "QmQP5C3PmhH9oB84n7YqSY4WVqmYatdoo1BdwhH4zmcwqM" } ], - "id": "61e1312b80705e0dabb948c9d78dae7f62d64832abda822b13d89c4a7305d4ac", + "id": "0fdeb547670bbea980389df53cf5a91e60159339084c6b0b5cc0b5494a679530", "inputs": [ { - "fulfillment": "pGSAIDE5i63cn4X8T8N1sZ2mGkJD5lNRnBM4PZgI_zvzbr-cgUCWcUaLa2U-nkmZ6oYj14aeV6B4TJH2NvZ8k2ZTwcGiaiCGXDQT2dEPfMCFwM8lwSousafCu4c7EgVZ1GzUDjsN", + "fulfillment": "pGSAIDE5i63cn4X8T8N1sZ2mGkJD5lNRnBM4PZgI_zvzbr-cgUDklzRb5aUQz9slbaqSWap1AfC-cacTCN3CGtFy2LPK7JKEqKG2b0KQXnUcFksk_KH_v6ImFXHsclKSp1OJkIEI", "fulfills": null, "owners_before": [ "4K9sWUMFwTgaDGPfdynrbxWqWS6sWmKbZoTjxLtVUibD" @@ -36,5 +34,5 @@ Content-Type: application/json ] } ], - "version": "2.0" + "version": "3.0" } diff --git a/planetmint/backend/connection.py b/planetmint/backend/connection.py index 3080d0b..ba63a8f 100644 --- a/planetmint/backend/connection.py +++ b/planetmint/backend/connection.py @@ -3,14 +3,12 @@ # SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0) # Code is Apache-2.0 and docs are CC-BY-4.0 -import tarantool import logging from itertools import repeat from importlib import import_module from transactions.common.exceptions import ConfigurationError from planetmint.config import Config -from planetmint.backend.exceptions import ConnectionError BACKENDS = { "tarantool_db": "planetmint.backend.tarantool.connection.TarantoolDBConnection", @@ -69,6 +67,7 @@ class DBConnection(metaclass=DBSingleton): **kwargs ): """Create a new :class:`~.Connection` instance. + Args: host (str): the host to connect to. port (int): the port to connect to. diff --git a/planetmint/backend/models/dbtransaction.py b/planetmint/backend/models/dbtransaction.py index 46c64b2..8119113 100644 --- a/planetmint/backend/models/dbtransaction.py +++ b/planetmint/backend/models/dbtransaction.py @@ -39,7 +39,9 @@ class DbTransaction: operation=transaction[1], version=transaction[2], metadata=MetaData.from_dict(transaction[3]), - assets=Asset.from_list_dict(transaction[4]), + assets=Asset.from_list_dict(transaction[4]) + if transaction[2] != "2.0" + else Asset.from_dict(transaction[4][0]), inputs=Input.from_list_dict(transaction[5]), script=Script.from_dict(transaction[6]), ) @@ -66,7 +68,7 @@ class DbTransaction: "outputs": Output.list_to_dict(self.outputs), "operation": self.operation, "metadata": self.metadata.to_dict() if self.metadata is not None else None, - "assets": Asset.list_to_dict(self.assets), + "assets": Asset.list_to_dict(self.assets) if self.version != "2.0" else Asset.to_dict(self.assets), "version": self.version, "id": self.id, "script": self.script.to_dict() if self.script is not None else None, diff --git a/planetmint/backend/query.py b/planetmint/backend/query.py index 5f60c6a..59be153 100644 --- a/planetmint/backend/query.py +++ b/planetmint/backend/query.py @@ -31,12 +31,12 @@ def store_asset(connection, asset: dict) -> Asset: @singledispatch def store_assets(connection, assets: list) -> list[Asset]: """Write a list of assets to the assets table. - backend - Args: - assets (list): a list of assets to write. - Returns: - The database response. + Args: + assets (list): a list of assets to write. + + Returns: + The database response. """ raise NotImplementedError @@ -70,27 +70,6 @@ def store_transaction(connection, transaction): raise NotImplementedError -@singledispatch -def store_governance_transactions(connection, transactions): - """Store the list of governance transactions.""" - - raise NotImplementedError - - -@singledispatch -def store_governance_transaction(connection, transaction): - """Store a single governance transaction.""" - - raise NotImplementedError - - -@singledispatch -def get_governance_transaction_by_id(connection, transaction_id): - """Get the transaction by transaction id.""" - - raise NotImplementedError - - @singledispatch def get_transaction_by_id(connection, transaction_id): """Get the transaction by transaction id.""" @@ -243,6 +222,7 @@ def store_transaction_outputs(connection, output: Output, index: int): @singledispatch def get_assets(connection, asset_ids) -> list[Asset]: """Get a list of assets from the assets table. + Args: asset_ids (list): a list of ids for the assets to be retrieved from the database. diff --git a/planetmint/backend/schema.py b/planetmint/backend/schema.py index 786a5c7..e3eceef 100644 --- a/planetmint/backend/schema.py +++ b/planetmint/backend/schema.py @@ -9,7 +9,6 @@ import logging from functools import singledispatch from planetmint.config import Config -from planetmint.backend.connection import Connection from transactions.common.exceptions import ValidationError from transactions.common.utils import ( validate_all_values_for_key_in_obj, diff --git a/planetmint/backend/tarantool/basic.lua b/planetmint/backend/tarantool/basic.lua deleted file mode 100644 index fcc46eb..0000000 --- a/planetmint/backend/tarantool/basic.lua +++ /dev/null @@ -1,78 +0,0 @@ -box.cfg{listen = 3303} - -function indexed_pattern_search(space_name, field_no, pattern) - if (box.space[space_name] == nil) then - print("Error: Failed to find the specified space") - return nil - end - local index_no = -1 - for i=0,box.schema.INDEX_MAX,1 do - if (box.space[space_name].index[i] == nil) then break end - if (box.space[space_name].index[i].type == "TREE" - and box.space[space_name].index[i].parts[1].fieldno == field_no - and (box.space[space_name].index[i].parts[1].type == "scalar" - or box.space[space_name].index[i].parts[1].type == "string")) then - index_no = i - break - end - end - if (index_no == -1) then - print("Error: Failed to find an appropriate index") - return nil - end - local index_search_key = "" - local index_search_key_length = 0 - local last_character = "" - local c = "" - local c2 = "" - for i=1,string.len(pattern),1 do - c = string.sub(pattern, i, i) - if (last_character ~= "%") then - if (c == '^' or c == "$" or c == "(" or c == ")" or c == "." - or c == "[" or c == "]" or c == "*" or c == "+" - or c == "-" or c == "?") then - break - end - if (c == "%") then - c2 = string.sub(pattern, i + 1, i + 1) - if (string.match(c2, "%p") == nil) then break end - index_search_key = index_search_key .. c2 - else - index_search_key = index_search_key .. c - end - end - last_character = c - end - index_search_key_length = string.len(index_search_key) - local result_set = {} - local number_of_tuples_in_result_set = 0 - local previous_tuple_field = "" - while true do - local number_of_tuples_since_last_yield = 0 - local is_time_for_a_yield = false - for _,tuple in box.space[space_name].index[index_no]: - pairs(index_search_key,{iterator = box.index.GE}) do - if (string.sub(tuple[field_no], 1, index_search_key_length) - > index_search_key) then - break - end - number_of_tuples_since_last_yield = number_of_tuples_since_last_yield + 1 - if (number_of_tuples_since_last_yield >= 10 - and tuple[field_no] ~= previous_tuple_field) then - index_search_key = tuple[field_no] - is_time_for_a_yield = true - break - end - previous_tuple_field = tuple[field_no] - if (string.match(tuple[field_no], pattern) ~= nil) then - number_of_tuples_in_result_set = number_of_tuples_in_result_set + 1 - result_set[number_of_tuples_in_result_set] = tuple - end - end - if (is_time_for_a_yield ~= true) then - break - end - require('fiber').yield() - end - return result_set -end \ No newline at end of file diff --git a/planetmint/backend/tarantool/connection.py b/planetmint/backend/tarantool/connection.py index 693cedb..476df1f 100644 --- a/planetmint/backend/tarantool/connection.py +++ b/planetmint/backend/tarantool/connection.py @@ -9,7 +9,8 @@ import tarantool from planetmint.config import Config from transactions.common.exceptions import ConfigurationError from planetmint.utils import Lazy -from planetmint.backend.connection import DBConnection, ConnectionError +from planetmint.backend.connection import DBConnection +from planetmint.backend.exceptions import ConnectionError logger = logging.getLogger(__name__) diff --git a/planetmint/backend/tarantool/const.py b/planetmint/backend/tarantool/const.py index 80b09e2..9efc9c1 100644 --- a/planetmint/backend/tarantool/const.py +++ b/planetmint/backend/tarantool/const.py @@ -11,6 +11,13 @@ TARANT_TABLE_GOVERNANCE = "governance" TARANT_TABLE_INPUT = "inputs" TARANT_TABLE_OUTPUT = "outputs" TARANT_TABLE_SCRIPT = "scripts" +TARANT_TABLE_BLOCKS = "blocks" +TARANT_TABLE_VALIDATOR_SETS = "validator_sets" +TARANT_TABLE_ABCI_CHAINS = "abci_chains" +TARANT_TABLE_UTXOS = "utxos" +TARANT_TABLE_PRE_COMMITS = "pre_commits" +TARANT_TABLE_ELECTIONS = "elections" + TARANT_TX_ID_SEARCH = "transaction_id" TARANT_ID_SEARCH = "id" diff --git a/planetmint/backend/tarantool/drop.lua b/planetmint/backend/tarantool/drop.lua deleted file mode 100644 index 563b782..0000000 --- a/planetmint/backend/tarantool/drop.lua +++ /dev/null @@ -1,8 +0,0 @@ -box.space.abci_chains:drop() -box.space.blocks:drop() -box.space.elections:drop() -box.space.pre_commits:drop() -box.space.utxos:drop() -box.space.validators:drop() -box.space.transactions:drop() -box.space.outputs:drop() diff --git a/planetmint/backend/tarantool/query.py b/planetmint/backend/tarantool/query.py index 7d8ce37..56279aa 100644 --- a/planetmint/backend/tarantool/query.py +++ b/planetmint/backend/tarantool/query.py @@ -7,8 +7,8 @@ import json import logging from uuid import uuid4 -from hashlib import sha256 from operator import itemgetter +from typing import Union from planetmint.backend import query @@ -18,9 +18,7 @@ from planetmint.exceptions import CriticalDoubleSpend from planetmint.backend.tarantool.const import ( TARANT_TABLE_META_DATA, TARANT_TABLE_ASSETS, - TARANT_TABLE_KEYS, TARANT_TABLE_TRANSACTION, - TARANT_TABLE_INPUT, TARANT_TABLE_OUTPUT, TARANT_TABLE_SCRIPT, TARANT_TX_ID_SEARCH, @@ -28,10 +26,17 @@ from planetmint.backend.tarantool.const import ( TARANT_INDEX_TX_BY_ASSET_ID, TARANT_INDEX_SPENDING_BY_ID_AND_OUTPUT_INDEX, TARANT_TABLE_GOVERNANCE, + TARANT_TABLE_ABCI_CHAINS, + TARANT_TABLE_BLOCKS, + TARANT_TABLE_VALIDATOR_SETS, + TARANT_TABLE_UTXOS, + TARANT_TABLE_PRE_COMMITS, + TARANT_TABLE_ELECTIONS, ) from planetmint.backend.utils import module_dispatch_registrar -from planetmint.backend.models import Asset, Block, MetaData, Input, Script, Output +from planetmint.backend.models import Asset, Block, Output from planetmint.backend.tarantool.connection import TarantoolDBConnection +from transactions.common.transaction import Transaction logger = logging.getLogger(__name__) @@ -39,7 +44,7 @@ register_query = module_dispatch_registrar(query) @register_query(TarantoolDBConnection) -def get_complete_transactions_by_ids(connection, txids: list, table=TARANT_TABLE_TRANSACTION) -> list[DbTransaction]: +def get_complete_transactions_by_ids(connection, txids: list) -> list[DbTransaction]: _transactions = [] for txid in txids: tx = get_transaction_by_id(connection, txid, TARANT_TABLE_TRANSACTION) @@ -61,7 +66,7 @@ def get_outputs_by_tx_id(connection, tx_id: str) -> list[Output]: @register_query(TarantoolDBConnection) -def get_transaction(connection, tx_id: str) -> DbTransaction: +def get_transaction(connection, tx_id: str) -> Union[DbTransaction, None]: transactions = get_complete_transactions_by_ids(connection, (tx_id)) if len(transactions) > 1 or len(transactions) == 0: return None @@ -109,9 +114,9 @@ def store_transaction_outputs(connection, output: Output, index: int) -> str: @register_query(TarantoolDBConnection) -def store_transactions(connection, signed_transactions: list): +def store_transactions(connection, signed_transactions: list, table=TARANT_TABLE_TRANSACTION): for transaction in signed_transactions: - store_transaction(connection, transaction) + store_transaction(connection, transaction, table) [ store_transaction_outputs(connection, Output.outputs_dict(output, transaction["id"]), index) for index, output in enumerate(transaction[TARANT_TABLE_OUTPUT]) @@ -119,81 +124,45 @@ def store_transactions(connection, signed_transactions: list): @register_query(TarantoolDBConnection) -def store_transaction(connection, transaction): +def store_transaction(connection, transaction, table=TARANT_TABLE_TRANSACTION): scripts = None if TARANT_TABLE_SCRIPT in transaction: scripts = transaction[TARANT_TABLE_SCRIPT] + asset_obj = Transaction.get_assets_tag(transaction["version"]) + if transaction["version"] == "2.0": + asset_array = [transaction[asset_obj]] + else: + asset_array = transaction[asset_obj] tx = ( transaction["id"], transaction["operation"], transaction["version"], transaction["metadata"], - transaction["assets"], + asset_array, transaction["inputs"], scripts, ) try: - connection.run(connection.space(TARANT_TABLE_TRANSACTION).insert(tx), only_data=False) + connection.run(connection.space(table).insert(tx), only_data=False) except Exception as e: logger.info(f"Could not insert transactions: {e}") - if e.args[0] == 3 and e.args[1].startswith('Duplicate key exists in'): + if e.args[0] == 3 and e.args[1].startswith("Duplicate key exists in"): raise CriticalDoubleSpend() else: raise OperationDataInsertionError() -@register_query(TarantoolDBConnection) -def store_governance_transactions(connection, signed_transactions: list): - for transaction in signed_transactions: - store_governance_transaction(connection, transaction) - [ - store_transaction_outputs(connection, Output.outputs_dict(output, transaction["id"]), index) - for index, output in enumerate(transaction[TARANT_TABLE_OUTPUT]) - ] - - -@register_query(TarantoolDBConnection) -def store_governance_transaction(connection, transaction): - scripts = None - if TARANT_TABLE_SCRIPT in transaction: - scripts = transaction[TARANT_TABLE_SCRIPT] - tx = ( - transaction["id"], - transaction["operation"], - transaction["version"], - transaction["metadata"], - transaction["assets"], - transaction["inputs"], - scripts, - ) - try: - connection.run(connection.space(TARANT_TABLE_GOVERNANCE).insert(tx), only_data=False) - except Exception as e: - if e.args[0] == 3 and e.args[1].startswith('Duplicate key exists in'): - raise CriticalDoubleSpend() - else: - raise OperationDataInsertionError() - - -@register_query(TarantoolDBConnection) -def get_governance_transaction_by_id(connection, transaction_id): - txs = connection.run(connection.space(TARANT_TABLE_GOVERNANCE).select(transaction_id, index=TARANT_ID_SEARCH)) - if len(txs) == 0: - return None - return DbTransaction.from_tuple(txs[0]) - - @register_query(TarantoolDBConnection) def get_transaction_by_id(connection, transaction_id, table=TARANT_TABLE_TRANSACTION): - txs = connection.run(connection.space(table).select(transaction_id, index=TARANT_ID_SEARCH)) + txs = connection.run(connection.space(table).select(transaction_id, index=TARANT_ID_SEARCH), only_data=False) if len(txs) == 0: return None return DbTransaction.from_tuple(txs[0]) @register_query(TarantoolDBConnection) -def get_transaction_single(connection, transaction_id, table=TARANT_TABLE_TRANSACTION) -> DbTransaction: - txs = get_complete_transactions_by_ids(txids=[transaction_id], connection=connection, table=table) +def get_transaction_single(connection, transaction_id) -> Union[DbTransaction, None]: + txs = get_complete_transactions_by_ids(txids=[transaction_id], connection=connection) return txs[0] if len(txs) == 1 else None @@ -224,7 +193,7 @@ def get_assets(connection, assets_ids: list) -> list[Asset]: @register_query(TarantoolDBConnection) -def get_spent(connection, fullfil_transaction_id: str, fullfil_output_index: str): +def get_spent(connection, fullfil_transaction_id: str, fullfil_output_index: str) -> list[DbTransaction]: _inputs = connection.run( connection.space(TARANT_TABLE_TRANSACTION).select( [fullfil_transaction_id, fullfil_output_index], index=TARANT_INDEX_SPENDING_BY_ID_AND_OUTPUT_INDEX @@ -234,8 +203,8 @@ def get_spent(connection, fullfil_transaction_id: str, fullfil_output_index: str @register_query(TarantoolDBConnection) -def get_latest_block(connection): - blocks = connection.run(connection.space("blocks").select()) +def get_latest_block(connection) -> Union[dict, None]: + blocks = connection.run(connection.space(TARANT_TABLE_BLOCKS).select()) if not blocks: return None @@ -249,7 +218,7 @@ def store_block(connection, block: dict): block_unique_id = uuid4().hex try: connection.run( - connection.space("blocks").insert( + connection.space(TARANT_TABLE_BLOCKS).insert( (block_unique_id, block["app_hash"], block["height"], block[TARANT_TABLE_TRANSACTION]) ), only_data=False, @@ -260,7 +229,7 @@ def store_block(connection, block: dict): @register_query(TarantoolDBConnection) -def get_txids_filtered(connection, asset_ids: list[str], operation: str = "", last_tx: bool = False): +def get_txids_filtered(connection, asset_ids: list[str], operation: str = "", last_tx: bool = False) -> list[str]: transactions = [] if operation == "CREATE": transactions = connection.run( @@ -308,7 +277,7 @@ def text_search(conn, search, table=TARANT_TABLE_ASSETS, limit=0): @register_query(TarantoolDBConnection) -def get_owned_ids(connection, owner: str): +def get_owned_ids(connection, owner: str) -> list[DbTransaction]: outputs = connection.run(connection.space(TARANT_TABLE_OUTPUT).select(owner, index="public_keys")) if len(outputs) == 0: return [] @@ -333,8 +302,8 @@ def get_spending_transactions(connection, inputs): @register_query(TarantoolDBConnection) -def get_block(connection, block_id=None): - _block = connection.run(connection.space("blocks").select(block_id, index="height", limit=1)) +def get_block(connection, block_id=None) -> Union[dict, None]: + _block = connection.run(connection.space(TARANT_TABLE_BLOCKS).select(block_id, index="height", limit=1)) if len(_block) == 0: return _block = Block.from_tuple(_block[0]) @@ -342,8 +311,8 @@ def get_block(connection, block_id=None): @register_query(TarantoolDBConnection) -def get_block_with_transaction(connection, txid: str): - _block = connection.run(connection.space("blocks").select(txid, index="block_by_transaction_id")) +def get_block_with_transaction(connection, txid: str) -> list[Block]: + _block = connection.run(connection.space(TARANT_TABLE_BLOCKS).select(txid, index="block_by_transaction_id")) return _block if len(_block) > 0 else [] @@ -351,7 +320,7 @@ def get_block_with_transaction(connection, txid: str): def delete_transactions(connection, txn_ids: list): try: for _id in txn_ids: - _outputs = get_outputs_by_tx_id( connection, _id) + _outputs = get_outputs_by_tx_id(connection, _id) for x in range(len(_outputs)): connection.connect().call("delete_output", (_outputs[x].id)) for _id in txn_ids: @@ -369,7 +338,9 @@ def store_unspent_outputs(connection, *unspent_outputs: list): for utxo in unspent_outputs: try: output = connection.run( - connection.space("utxos").insert((uuid4().hex, utxo["transaction_id"], utxo["output_index"], utxo)) + connection.space(TARANT_TABLE_UTXOS).insert( + (uuid4().hex, utxo["transaction_id"], utxo["output_index"], utxo) + ) ) result.append(output) except Exception as e: @@ -384,7 +355,7 @@ def delete_unspent_outputs(connection, *unspent_outputs: list): if unspent_outputs: for utxo in unspent_outputs: output = connection.run( - connection.space("utxos").delete( + connection.space(TARANT_TABLE_UTXOS).delete( (utxo["transaction_id"], utxo["output_index"]), index="utxo_by_transaction_id_and_output_index" ) ) @@ -394,13 +365,13 @@ def delete_unspent_outputs(connection, *unspent_outputs: list): @register_query(TarantoolDBConnection) def get_unspent_outputs(connection, query=None): # for now we don't have implementation for 'query'. - _utxos = connection.run(connection.space("utxos").select([])) + _utxos = connection.run(connection.space(TARANT_TABLE_UTXOS).select([])) return [utx[3] for utx in _utxos] @register_query(TarantoolDBConnection) def store_pre_commit_state(connection, state: dict): - _precommit = connection.run(connection.space("pre_commits").select([], limit=1)) + _precommit = connection.run(connection.space(TARANT_TABLE_PRE_COMMITS).select([], limit=1)) _precommitTuple = ( (uuid4().hex, state["height"], state[TARANT_TABLE_TRANSACTION]) if _precommit is None or len(_precommit) == 0 @@ -408,7 +379,7 @@ def store_pre_commit_state(connection, state: dict): ) try: connection.run( - connection.space("pre_commits").upsert( + connection.space(TARANT_TABLE_PRE_COMMITS).upsert( _precommitTuple, op_list=[("=", 1, state["height"]), ("=", 2, state[TARANT_TABLE_TRANSACTION])], limit=1, @@ -421,8 +392,8 @@ def store_pre_commit_state(connection, state: dict): @register_query(TarantoolDBConnection) -def get_pre_commit_state(connection): - _commit = connection.run(connection.space("pre_commits").select([], index=TARANT_ID_SEARCH)) +def get_pre_commit_state(connection) -> dict: + _commit = connection.run(connection.space(TARANT_TABLE_PRE_COMMITS).select([], index=TARANT_ID_SEARCH)) if _commit is None or len(_commit) == 0: return None _commit = sorted(_commit, key=itemgetter(1), reverse=False)[0] @@ -431,11 +402,13 @@ def get_pre_commit_state(connection): @register_query(TarantoolDBConnection) def store_validator_set(conn, validators_update: dict): - _validator = conn.run(conn.space("validator_sets").select(validators_update["height"], index="height", limit=1)) + _validator = conn.run( + conn.space(TARANT_TABLE_VALIDATOR_SETS).select(validators_update["height"], index="height", limit=1) + ) unique_id = uuid4().hex if _validator is None or len(_validator) == 0 else _validator[0][0] try: conn.run( - conn.space("validator_sets").upsert( + conn.space(TARANT_TABLE_VALIDATOR_SETS).upsert( (unique_id, validators_update["height"], validators_update["validators"]), op_list=[("=", 1, validators_update["height"]), ("=", 2, validators_update["validators"])], limit=1, @@ -449,16 +422,16 @@ def store_validator_set(conn, validators_update: dict): @register_query(TarantoolDBConnection) def delete_validator_set(connection, height: int): - _validators = connection.run(connection.space("validator_sets").select(height, index="height")) + _validators = connection.run(connection.space(TARANT_TABLE_VALIDATOR_SETS).select(height, index="height")) for _valid in _validators: - connection.run(connection.space("validator_sets").delete(_valid[0]), only_data=False) + connection.run(connection.space(TARANT_TABLE_VALIDATOR_SETS).delete(_valid[0]), only_data=False) @register_query(TarantoolDBConnection) def store_election(connection, election_id: str, height: int, is_concluded: bool): try: connection.run( - connection.space("elections").upsert( + connection.space(TARANT_TABLE_ELECTIONS).upsert( (election_id, height, is_concluded), op_list=[("=", 1, height), ("=", 2, is_concluded)], limit=1 ), only_data=False, @@ -473,7 +446,7 @@ def store_elections(connection, elections: list): try: for election in elections: _election = connection.run( # noqa: F841 - connection.space("elections").insert( + connection.space(TARANT_TABLE_ELECTIONS).insert( (election["election_id"], election["height"], election["is_concluded"]) ), only_data=False, @@ -485,14 +458,14 @@ def store_elections(connection, elections: list): @register_query(TarantoolDBConnection) def delete_elections(connection, height: int): - _elections = connection.run(connection.space("elections").select(height, index="height")) + _elections = connection.run(connection.space(TARANT_TABLE_ELECTIONS).select(height, index="height")) for _elec in _elections: - connection.run(connection.space("elections").delete(_elec[0]), only_data=False) + connection.run(connection.space(TARANT_TABLE_ELECTIONS).delete(_elec[0]), only_data=False) @register_query(TarantoolDBConnection) def get_validator_set(connection, height: int = None): - _validators = connection.run(connection.space("validator_sets").select()) + _validators = connection.run(connection.space(TARANT_TABLE_VALIDATOR_SETS).select()) if height is not None and _validators is not None: _validators = [ {"height": validator[1], "validators": validator[2]} for validator in _validators if validator[1] <= height @@ -505,8 +478,8 @@ def get_validator_set(connection, height: int = None): @register_query(TarantoolDBConnection) -def get_election(connection, election_id: str): - _elections = connection.run(connection.space("elections").select(election_id, index=TARANT_ID_SEARCH)) +def get_election(connection, election_id: str) -> dict: + _elections = connection.run(connection.space(TARANT_TABLE_ELECTIONS).select(election_id, index=TARANT_ID_SEARCH)) if _elections is None or len(_elections) == 0: return None _election = sorted(_elections, key=itemgetter(0), reverse=True)[0] @@ -515,29 +488,19 @@ def get_election(connection, election_id: str): @register_query(TarantoolDBConnection) def get_asset_tokens_for_public_key(connection, asset_id: str, public_key: str) -> list[DbTransaction]: - # FIXME Something can be wrong with this function ! (public_key) is not used # noqa: E501 - # space = connection.space("keys") - # _keys = space.select([public_key], index="keys_search") - # _transactions = connection.run(connection.space(TARANT_TABLE_ASSETS).select([asset_id], index="assetid_search")) - # _transactions = _transactions - # _keys = _keys.data id_transactions = connection.run(connection.space(TARANT_TABLE_GOVERNANCE).select([asset_id])) asset_id_transactions = connection.run( connection.space(TARANT_TABLE_GOVERNANCE).select([asset_id], index="governance_by_asset_id") ) transactions = id_transactions + asset_id_transactions - - # TODO return transaction class - # return transactions - return get_complete_transactions_by_ids(connection, [_tx[0] for _tx in transactions], TARANT_TABLE_GOVERNANCE) - # return get_complete_transactions_by_ids(connection=connection, txids=[_tx[1] for _tx in transactions]) + return get_complete_transactions_by_ids(connection, [_tx[0] for _tx in transactions]) @register_query(TarantoolDBConnection) def store_abci_chain(connection, height: int, chain_id: str, is_synced: bool = True): try: connection.run( - connection.space("abci_chains").upsert( + connection.space(TARANT_TABLE_ABCI_CHAINS).upsert( (chain_id, height, is_synced), op_list=[("=", 0, chain_id), ("=", 1, height), ("=", 2, is_synced)], ), @@ -550,15 +513,13 @@ def store_abci_chain(connection, height: int, chain_id: str, is_synced: bool = T @register_query(TarantoolDBConnection) def delete_abci_chain(connection, height: int): - hash_id_primarykey = sha256(json.dumps(obj={"height": height}).encode()).hexdigest() - # connection.run(connection.space("abci_chains").delete(hash_id_primarykey), only_data=False) - chains = connection.run(connection.space("abci_chains").select(height, index="height"), only_data=False) - connection.run(connection.space("abci_chains").delete(chains[0][0], index="id"), only_data=False) + chains = connection.run(connection.space(TARANT_TABLE_ABCI_CHAINS).select(height, index="height"), only_data=False) + connection.run(connection.space(TARANT_TABLE_ABCI_CHAINS).delete(chains[0][0], index="id"), only_data=False) @register_query(TarantoolDBConnection) -def get_latest_abci_chain(connection): - _all_chains = connection.run(connection.space("abci_chains").select()) +def get_latest_abci_chain(connection) -> Union[dict, None]: + _all_chains = connection.run(connection.space(TARANT_TABLE_ABCI_CHAINS).select()) if _all_chains is None or len(_all_chains) == 0: return None _chain = sorted(_all_chains, key=itemgetter(1), reverse=True)[0] diff --git a/planetmint/backend/tarantool/schema.py b/planetmint/backend/tarantool/schema.py index 23bde15..531cdb2 100644 --- a/planetmint/backend/tarantool/schema.py +++ b/planetmint/backend/tarantool/schema.py @@ -8,142 +8,6 @@ from planetmint.backend.tarantool.connection import TarantoolDBConnection logger = logging.getLogger(__name__) register_schema = module_dispatch_registrar(backend.schema) -SPACE_NAMES = ( - "abci_chains", - "assets", - "blocks", - "blocks_tx", - "elections", - "meta_data", - "pre_commits", - "validators", - "transactions", - "inputs", - "outputs", - "keys", - "utxos", - "scripts", -) - - -SPACE_COMMANDS = { - "abci_chains": "abci_chains = box.schema.space.create('abci_chains', {engine='memtx', is_sync = false})", - "assets": "assets = box.schema.space.create('assets' , {engine='memtx' , is_sync=false})", - "blocks": "blocks = box.schema.space.create('blocks' , {engine='memtx' , is_sync=false})", - "blocks_tx": "blocks_tx = box.schema.space.create('blocks_tx')", - "elections": "elections = box.schema.space.create('elections',{engine = 'memtx' , is_sync = false})", - "meta_data": "meta_datas = box.schema.space.create('meta_data',{engine = 'memtx' , is_sync = false})", - "pre_commits": "pre_commits = box.schema.space.create('pre_commits' , {engine='memtx' , is_sync=false})", - "validators": "validators = box.schema.space.create('validators' , {engine = 'memtx' , is_sync = false})", - "transactions": "transactions = box.schema.space.create('transactions',{engine='memtx' , is_sync=false})", - "inputs": "inputs = box.schema.space.create('inputs')", - "outputs": "outputs = box.schema.space.create('outputs')", - "keys": "keys = box.schema.space.create('keys')", - "utxos": "utxos = box.schema.space.create('utxos', {engine = 'memtx' , is_sync = false})", - "scripts": "scripts = box.schema.space.create('scripts', {engine = 'memtx' , is_sync = false})", -} - -INDEX_COMMANDS = { - "abci_chains": { - "id_search": "abci_chains:create_index('id_search' ,{type='tree', parts={'id'}})", - "height_search": "abci_chains:create_index('height_search' ,{type='tree', unique=false, parts={'height'}})", - }, - "assets": { - "txid_search": "assets:create_index('txid_search', {type='tree', parts={'tx_id'}})", - "assetid_search": "assets:create_index('assetid_search', {type='tree',unique=false, parts={'asset_id', 'tx_id'}})", # noqa: E501 - "only_asset_search": "assets:create_index('only_asset_search', {type='tree', unique=false, parts={'asset_id'}})", # noqa: E501 - "text_search": "assets:create_index('secondary', {unique=false,parts={1,'string'}})", - }, - "blocks": { - "id_search": "blocks:create_index('id_search' , {type='tree' , parts={'block_id'}})", - "block_search": "blocks:create_index('block_search' , {type='tree', unique = false, parts={'height'}})", - "block_id_search": "blocks:create_index('block_id_search', {type = 'hash', parts ={'block_id'}})", - }, - "blocks_tx": { - "id_search": "blocks_tx:create_index('id_search',{ type = 'tree', parts={'transaction_id'}})", - "block_search": "blocks_tx:create_index('block_search', {type = 'tree',unique=false, parts={'block_id'}})", - }, - "elections": { - "id_search": "elections:create_index('id_search' , {type='tree', parts={'election_id'}})", - "height_search": "elections:create_index('height_search' , {type='tree',unique=false, parts={'height'}})", - "update_search": "elections:create_index('update_search', {type='tree', unique=false, parts={'election_id', 'height'}})", # noqa: E501 - }, - "meta_data": { - "id_search": "meta_datas:create_index('id_search', { type='tree' , parts={'transaction_id'}})", - "text_search": "meta_datas:create_index('secondary', {unique=false,parts={2,'string'}})", - }, - "pre_commits": { - "id_search": "pre_commits:create_index('id_search', {type ='tree' , parts={'commit_id'}})", - "height_search": "pre_commits:create_index('height_search', {type ='tree',unique=true, parts={'height'}})", - }, - "validators": { - "id_search": "validators:create_index('id_search' , {type='tree' , parts={'validator_id'}})", - "height_search": "validators:create_index('height_search' , {type='tree', unique=true, parts={'height'}})", - }, - "transactions": { - "id_search": "transactions:create_index('id_search' , {type = 'tree' , parts={'transaction_id'}})", - "transaction_search": "transactions:create_index('transaction_search' , {type = 'tree',unique=false, parts={'operation', 'transaction_id'}})", # noqa: E501 - }, - "inputs": { - "delete_search": "inputs:create_index('delete_search' , {type = 'tree', parts={'input_id'}})", - "spent_search": "inputs:create_index('spent_search' , {type = 'tree', unique=false, parts={'fulfills_transaction_id', 'fulfills_output_index'}})", # noqa: E501 - "id_search": "inputs:create_index('id_search', {type = 'tree', unique=false, parts = {'transaction_id'}})", - }, - "outputs": { - "unique_search": "outputs:create_index('unique_search' ,{type='tree', parts={'output_id'}})", - "id_search": "outputs:create_index('id_search' ,{type='tree', unique=false, parts={'transaction_id'}})", - }, - "keys": { - "id_search": "keys:create_index('id_search', {type = 'tree', parts={'id'}})", - "keys_search": "keys:create_index('keys_search', {type = 'tree', unique=false, parts={'public_key'}})", - "txid_search": "keys:create_index('txid_search', {type = 'tree', unique=false, parts={'transaction_id'}})", - "output_search": "keys:create_index('output_search', {type = 'tree', unique=false, parts={'output_id'}})", - }, - "utxos": { - "id_search": "utxos:create_index('id_search', {type='tree' , parts={'transaction_id', 'output_index'}})", - "transaction_search": "utxos:create_index('transaction_search', {type='tree', unique=false, parts={'transaction_id'}})", # noqa: E501 - "index_Search": "utxos:create_index('index_search', {type='tree', unique=false, parts={'output_index'}})", - }, - "scripts": { - "txid_search": "scripts:create_index('txid_search', {type='tree', parts={'transaction_id'}})", - }, -} - - -SCHEMA_COMMANDS = { - "abci_chains": "abci_chains:format({{name='height' , type='integer'},{name='is_synched' , type='boolean'},{name='chain_id',type='string'}, {name='id', type='string'}})", # noqa: E501 - "assets": "assets:format({{name='data' , type='string'}, {name='tx_id', type='string'}, {name='asset_id', type='string'}})", # noqa: E501 - "blocks": "blocks:format{{name='app_hash',type='string'},{name='height' , type='integer'},{name='block_id' , type='string'}}", # noqa: E501 - "blocks_tx": "blocks_tx:format{{name='transaction_id', type = 'string'}, {name = 'block_id', type = 'string'}}", - "elections": "elections:format({{name='election_id' , type='string'},{name='height' , type='integer'}, {name='is_concluded' , type='boolean'}})", # noqa: E501 - "meta_data": "meta_datas:format({{name='transaction_id' , type='string'}, {name='meta_data' , type='string'}})", # noqa: E501 - "pre_commits": "pre_commits:format({{name='commit_id', type='string'}, {name='height',type='integer'}, {name='transactions',type=any}})", # noqa: E501 - "validators": "validators:format({{name='validator_id' , type='string'},{name='height',type='integer'},{name='validators' , type='any'}})", # noqa: E501 - "transactions": "transactions:format({{name='transaction_id' , type='string'}, {name='operation' , type='string'}, {name='version' ,type='string'}, {name='dict_map', type='any'}})", # noqa: E501 - "inputs": "inputs:format({{name='transaction_id' , type='string'}, {name='fulfillment' , type='any'}, {name='owners_before' , type='array'}, {name='fulfills_transaction_id', type = 'string'}, {name='fulfills_output_index', type = 'string'}, {name='input_id', type='string'}, {name='input_index', type='number'}})", # noqa: E501 - "outputs": "outputs:format({{name='transaction_id' , type='string'}, {name='amount' , type='string'}, {name='uri', type='string'}, {name='details_type', type='string'}, {name='details_public_key', type='any'}, {name = 'output_id', type = 'string'}, {name='treshold', type='any'}, {name='subconditions', type='any'}, {name='output_index', type='number'}})", # noqa: E501 - "keys": "keys:format({{name = 'id', type='string'}, {name = 'transaction_id', type = 'string'} ,{name = 'output_id', type = 'string'}, {name = 'public_key', type = 'string'}, {name = 'key_index', type = 'integer'}})", # noqa: E501 - "utxos": "utxos:format({{name='transaction_id' , type='string'}, {name='output_index' , type='integer'}, {name='utxo_dict', type='string'}})", # noqa: E501 - "scripts": "scripts:format({{name='transaction_id', type='string'},{name='script' , type='any'}})", # noqa: E501 -} - -SCHEMA_DROP_COMMANDS = { - "abci_chains": "box.space.abci_chains:drop()", - "assets": "box.space.assets:drop()", - "blocks": "box.space.blocks:drop()", - "blocks_tx": "box.space.blocks_tx:drop()", - "elections": "box.space.elections:drop()", - "meta_data": "box.space.meta_data:drop()", - "pre_commits": "box.space.pre_commits:drop()", - "validators": "box.space.validators:drop()", - "transactions": "box.space.transactions:drop()", - "inputs": "box.space.inputs:drop()", - "outputs": "box.space.outputs:drop()", - "keys": "box.space.keys:drop()", - "utxos": "box.space.utxos:drop()", - "scripts": "box.space.scripts:drop()", -} - @register_schema(TarantoolDBConnection) def init_database(connection, db_name=None): diff --git a/planetmint/commands/planetmint.py b/planetmint/commands/planetmint.py index c8b4a9c..bba0f7a 100644 --- a/planetmint/commands/planetmint.py +++ b/planetmint/commands/planetmint.py @@ -196,7 +196,7 @@ def run_election_approve(args, planet): """ key = load_node_key(args.sk) - tx = planet.get_transaction(args.election_id, TARANT_TABLE_GOVERNANCE) + tx = planet.get_transaction(args.election_id) voting_powers = [v.amount for v in tx.outputs if key.public_key in v.public_keys] if len(voting_powers) > 0: voting_power = voting_powers[0] @@ -230,7 +230,7 @@ def run_election_show(args, planet): :param planet: an instance of Planetmint """ - election = planet.get_transaction(args.election_id, TARANT_TABLE_GOVERNANCE) + election = planet.get_transaction(args.election_id) if not election: logger.error(f"No election found with election_id {args.election_id}") return diff --git a/planetmint/lib.py b/planetmint/lib.py index ca8048b..334d714 100644 --- a/planetmint/lib.py +++ b/planetmint/lib.py @@ -163,8 +163,8 @@ class Planetmint(object): else: txns.append(transaction) - backend.query.store_transactions(self.connection, txns) - backend.query.store_governance_transactions(self.connection, gov_txns) + backend.query.store_transactions(self.connection, txns, TARANT_TABLE_TRANSACTION) + backend.query.store_transactions(self.connection, gov_txns, TARANT_TABLE_GOVERNANCE) def delete_transactions(self, txs): return backend.query.delete_transactions(self.connection, txs) @@ -245,12 +245,12 @@ class Planetmint(object): if unspent_outputs: return backend.query.delete_unspent_outputs(self.connection, *unspent_outputs) - def is_committed(self, transaction_id, table=TARANT_TABLE_TRANSACTION): - transaction = backend.query.get_transaction_by_id(self.connection, transaction_id, table) + def is_committed(self, transaction_id): + transaction = backend.query.get_transaction_single(self.connection, transaction_id) return bool(transaction) - def get_transaction(self, transaction_id, table=TARANT_TABLE_TRANSACTION): - return backend.query.get_transaction_single(self.connection, transaction_id, table) + def get_transaction(self, transaction_id): + return backend.query.get_transaction_single(self.connection, transaction_id) def get_transactions(self, txn_ids): return backend.query.get_transactions(self.connection, txn_ids) @@ -261,9 +261,6 @@ class Planetmint(object): for txid in txids: yield self.get_transaction(txid) - def get_governance_transaction(self, transaction_id): - return backend.query.get_governance_transaction_by_id(self.connection, transaction_id) - def get_outputs_by_tx_id(self, txid): return backend.query.get_outputs_by_tx_id(self.connection, txid) @@ -390,13 +387,9 @@ class Planetmint(object): input_txs = [] input_conditions = [] - table = TARANT_TABLE_TRANSACTION - if tx.operation in GOVERNANCE_TRANSACTION_TYPES: - table = TARANT_TABLE_GOVERNANCE - for input_ in tx.inputs: input_txid = input_.fulfills.txid - input_tx = self.get_transaction(input_txid, table) + input_tx = self.get_transaction(input_txid) _output = self.get_outputs_by_tx_id(input_txid) if input_tx is None: for ctxn in current_transactions: @@ -430,7 +423,7 @@ class Planetmint(object): # validate asset id asset_id = tx.get_asset_id(input_txs) - if asset_id != tx.assets[0]["id"]: + if asset_id != Transaction.read_out_asset_id(tx): raise AssetIdMismatch(("The asset id of the input does not" " match the asset id of the" " transaction")) # convert planetmint.Output objects to transactions.common.Output objects @@ -614,7 +607,7 @@ class Planetmint(object): """ duplicates = any(txn for txn in current_transactions if txn.id == transaction.id) - if self.is_committed(transaction.id, TARANT_TABLE_GOVERNANCE) or duplicates: + if self.is_committed(transaction.id) or duplicates: raise DuplicateTransaction("transaction `{}` already exists".format(transaction.id)) current_validators = self.get_validators_dict() @@ -823,7 +816,7 @@ class Planetmint(object): validator_update = None for election_id, votes in elections.items(): - election = self.get_transaction(election_id, TARANT_TABLE_GOVERNANCE) + election = self.get_transaction(election_id) if election is None: continue @@ -899,7 +892,7 @@ class Planetmint(object): self.delete_elections(new_height) txns = [self.get_transaction(tx_id) for tx_id in txn_ids] - + txns = [Transaction.from_dict(tx.to_dict()) for tx in txns] elections = self._get_votes(txns) diff --git a/planetmint/version.py b/planetmint/version.py index 643df2c..f4bc962 100644 --- a/planetmint/version.py +++ b/planetmint/version.py @@ -3,8 +3,8 @@ # 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.3.2" -__short_version__ = "1.3" +__version__ = "1.4.1" +__short_version__ = "1.4" # Supported Tendermint versions __tm_supported_versions__ = ["0.34.15"] diff --git a/planetmint/web/views/transactions.py b/planetmint/web/views/transactions.py index 2660588..39fe56c 100644 --- a/planetmint/web/views/transactions.py +++ b/planetmint/web/views/transactions.py @@ -92,6 +92,13 @@ class TransactionListApi(Resource): except ValidationError as e: return make_error(400, "Invalid transaction ({}): {}".format(type(e).__name__, e)) else: + if tx_obj.version != Transaction.VERSION: + return make_error( + 401, + "Invalid transaction version: The transaction is valid, \ + but this node only accepts transaction with higher \ + schema version number.", + ) status_code, message = planet.write_transaction(tx_obj, mode) if status_code == 202: diff --git a/setup.py b/setup.py index 8a248bb..a9fc93b 100644 --- a/setup.py +++ b/setup.py @@ -103,7 +103,6 @@ tests_require = [ "pytest-flask", "pytest-aiohttp", "pytest-asyncio", - "tox", ] + docs_require install_requires = [ @@ -130,7 +129,7 @@ install_requires = [ "planetmint-ipld>=0.0.3", "pyasn1>=0.4.8", "python-decouple", - # "planetmint-transactions>=0.2.2", + "planetmint-transactions>=0.5.0", ] setup( diff --git a/tests/assets/test_digital_assets.py b/tests/assets/test_digital_assets.py index eaf4a10..e0e678d 100644 --- a/tests/assets/test_digital_assets.py +++ b/tests/assets/test_digital_assets.py @@ -9,7 +9,7 @@ from transactions.types.assets.create import Create from transactions.types.assets.transfer import Transfer -def test_asset_transfer(b, signed_create_tx, user_pk, user_sk): +def test_asset_transfer(b, signed_create_tx, user_pk, user_sk, _bdb): tx_transfer = Transfer.generate(signed_create_tx.to_inputs(), [([user_pk], 1)], [signed_create_tx.id]) tx_transfer_signed = tx_transfer.sign([user_sk]) @@ -24,7 +24,7 @@ def test_asset_transfer(b, signed_create_tx, user_pk, user_sk): # from planetmint.transactions.common.exceptions import AssetIdMismatch -def test_validate_transfer_asset_id_mismatch(b, signed_create_tx, user_pk, user_sk): +def test_validate_transfer_asset_id_mismatch(b, signed_create_tx, user_pk, user_sk, _bdb): from transactions.common.exceptions import AssetIdMismatch tx_transfer = Transfer.generate(signed_create_tx.to_inputs(), [([user_pk], 1)], [signed_create_tx.id]) @@ -69,7 +69,23 @@ def test_asset_id_mismatch(alice, user_pk): Transaction.get_asset_id([tx1, tx2]) -def test_create_valid_divisible_asset(b, user_pk, user_sk): +def test_create_valid_divisible_asset(b, user_pk, user_sk, _bdb): tx = Create.generate([user_pk], [([user_pk], 2)]) tx_signed = tx.sign([user_sk]) assert b.validate_transaction(tx_signed) == tx_signed + + +def test_v_2_0_validation_create(b, signed_2_0_create_tx, _bdb): + validated = b.validate_transaction(signed_2_0_create_tx) + assert validated.to_dict() == signed_2_0_create_tx + + +def test_v_2_0_validation_create_invalid(b, signed_2_0_create_tx_assets, _bdb): + assert b.validate_transaction(signed_2_0_create_tx_assets) + + +def test_v_2_0_validation_transfer(b, signed_2_0_create_tx, signed_2_0_transfer_tx, _bdb): + validated = b.validate_transaction(signed_2_0_create_tx) + b.store_bulk_transactions([validated]) + assert validated.to_dict() == signed_2_0_create_tx + assert b.validate_transaction(signed_2_0_transfer_tx).to_dict() == signed_2_0_transfer_tx diff --git a/tests/backend/tarantool/test_schema.py b/tests/backend/tarantool/test_schema.py index 82eb0b4..3d116dd 100644 --- a/tests/backend/tarantool/test_schema.py +++ b/tests/backend/tarantool/test_schema.py @@ -3,8 +3,6 @@ # SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0) # Code is Apache-2.0 and docs are CC-BY-4.0 -from planetmint.backend.tarantool.connection import TarantoolDBConnection - def _check_spaces_by_list(conn, space_names): _exists = [] diff --git a/tests/backend/test_connection.py b/tests/backend/test_connection.py index 94e7615..fdd0aa9 100644 --- a/tests/backend/test_connection.py +++ b/tests/backend/test_connection.py @@ -7,7 +7,7 @@ import pytest def test_get_connection_raises_a_configuration_error(monkeypatch): - from planetmint.backend.connection import ConnectionError + from planetmint.backend.exceptions import ConnectionError from planetmint.backend.tarantool.connection import TarantoolDBConnection with pytest.raises(ConnectionError): diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index 2cfd9a8..3252b1f 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -14,7 +14,6 @@ from planetmint import ValidatorElection from planetmint.commands.planetmint import run_election_show from planetmint.commands.planetmint import run_election_new_chain_migration from planetmint.backend.connection import Connection -from planetmint.backend.tarantool.const import TARANT_TABLE_GOVERNANCE from planetmint.lib import Block from transactions.types.elections.chain_migration_election import ChainMigrationElection @@ -323,7 +322,7 @@ def test_election_new_upsert_validator_with_tendermint(b, priv_validator_path, u election_id = run_election_new_upsert_validator(new_args, b) - assert b.get_transaction(election_id, TARANT_TABLE_GOVERNANCE) + assert b.get_transaction(election_id) @pytest.mark.bdb @@ -350,7 +349,7 @@ def test_election_new_upsert_validator_without_tendermint(caplog, b, priv_valida with caplog.at_level(logging.INFO): election_id = run_election_new_upsert_validator(args, b) assert caplog.records[0].msg == "[SUCCESS] Submitted proposal with id: " + election_id - assert b.get_transaction(election_id, TARANT_TABLE_GOVERNANCE) + assert b.get_transaction(election_id) @pytest.mark.abci @@ -359,7 +358,7 @@ def test_election_new_chain_migration_with_tendermint(b, priv_validator_path, us election_id = run_election_new_chain_migration(new_args, b) - assert b.get_transaction(election_id, TARANT_TABLE_GOVERNANCE) + assert b.get_transaction(election_id) @pytest.mark.bdb @@ -376,7 +375,7 @@ def test_election_new_chain_migration_without_tendermint(caplog, b, priv_validat with caplog.at_level(logging.INFO): election_id = run_election_new_chain_migration(args, b) assert caplog.records[0].msg == "[SUCCESS] Submitted proposal with id: " + election_id - assert b.get_transaction(election_id, TARANT_TABLE_GOVERNANCE) + assert b.get_transaction(election_id) @pytest.mark.bdb @@ -445,7 +444,7 @@ def test_election_approve_with_tendermint(b, priv_validator_path, user_sk, valid args = Namespace(action="approve", election_id=election_id, sk=priv_validator_path, config={}) approve = run_election_approve(args, b) - assert b.get_transaction(approve, TARANT_TABLE_GOVERNANCE) + assert b.get_transaction(approve) @pytest.mark.bdb @@ -462,7 +461,7 @@ def test_election_approve_without_tendermint(caplog, b, priv_validator_path, new with caplog.at_level(logging.INFO): approval_id = run_election_approve(args, b) assert caplog.records[0].msg == "[SUCCESS] Your vote has been submitted" - assert b.get_transaction(approval_id, TARANT_TABLE_GOVERNANCE) + assert b.get_transaction(approval_id) @pytest.mark.bdb diff --git a/tests/conftest.py b/tests/conftest.py index 09d6e49..2d72e0e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -27,7 +27,6 @@ from transactions.common.transaction_mode_types import BROADCAST_TX_COMMIT from planetmint.tendermint_utils import key_from_base64 from planetmint.backend import schema, query from transactions.common.crypto import key_pair_from_ed25519_key, public_key_from_ed25519_key -from transactions.common.exceptions import DatabaseDoesNotExist from planetmint.lib import Block from tests.utils import gen_vote from planetmint.config import Config @@ -736,3 +735,110 @@ def generate_votes(election, voters, keys): v = gen_vote(election, voter, keys) votes.append(v) return votes + + +@pytest.fixture +def signed_2_0_create_tx(): + return { + "inputs": [ + { + "owners_before": ["7WaJCRqUJMZjVyQxqq8GNjkw11gacFmDAZGPLdNxfBgx"], + "fulfills": None, + "fulfillment": "pGSAIGC5nQ37hCCMAWIUBAJn4wVBOkHlURaWzWLjE5rTzG91gUC0Akx2m_AoPy1H6yTz7Ou2I-OGjNjWgvR5EATn8XZ1u-g91XL3CkSXXiL2sUJqDibJQJjGZjag_7fRu5_VkDUD", + } + ], + "outputs": [ + { + "public_keys": ["7WaJCRqUJMZjVyQxqq8GNjkw11gacFmDAZGPLdNxfBgx"], + "condition": { + "details": { + "type": "ed25519-sha-256", + "public_key": "7WaJCRqUJMZjVyQxqq8GNjkw11gacFmDAZGPLdNxfBgx", + }, + "uri": "ni:///sha-256;xtKK2YRiX7_EPF2harsf-PELcJwfHQM7jZ_YvilEOOI?fpt=ed25519-sha-256&cost=131072", + }, + "amount": "3000", + } + ], + "operation": "CREATE", + "metadata": "QmRBri4SARi56PgB2ALFVjHsLhQDUh4jYbeiHaU94vLoxd", + "asset": {"data": "QmW5GVMW98D3mktSDfWHS8nX2UiCd8gP1uCiujnFX4yK8n"}, + "version": "2.0", + "id": "334014a29d99a488789c711b7dc5fceb534d1a9290b14d0270dbe6b60e2f036e", + } + + +@pytest.fixture +def signed_2_0_create_tx_assets(): + return { + "inputs": [ + { + "owners_before": ["5V4AANHTSLdQH1mEA1pohW3jMduY9xMJ1voos7gRfMQF"], + "fulfills": None, + "fulfillment": "pGSAIEKelMEu8AzcA9kcDLrsEXhSpZG-lf2c9CuZpzZU_ONkgUBMztcnweWqwHVfVk9Y-IRgfdh864yXYTrTKzSMy6uvNjQeLtGzKxz4gjb01NUu6WLvZBAvr0Ws4glfxKiDLjkP", + } + ], + "outputs": [ + { + "public_keys": ["5V4AANHTSLdQH1mEA1pohW3jMduY9xMJ1voos7gRfMQF"], + "condition": { + "details": { + "type": "ed25519-sha-256", + "public_key": "5V4AANHTSLdQH1mEA1pohW3jMduY9xMJ1voos7gRfMQF", + }, + "uri": "ni:///sha-256;M3l9yVs7ItjP-lxT7B2ta6rpRa-GHt6TBSYpy8l-IS8?fpt=ed25519-sha-256&cost=131072", + }, + "amount": "3000", + } + ], + "operation": "CREATE", + "metadata": "QmRBri4SARi56PgB2ALFVjHsLhQDUh4jYbeiHaU94vLoxd", + "assets": {"data": "QmW5GVMW98D3mktSDfWHS8nX2UiCd8gP1uCiujnFX4yK8n"}, + "version": "2.0", + "id": "3e2a2c5eef5e6a0c4e1e5f8d0dc1d3d9b4f035592a9788f8bfa7d59f86d123d3", + } + + +@pytest.fixture +def signed_2_0_transfer_tx(): + return { + "inputs": [ + { + "owners_before": ["7WaJCRqUJMZjVyQxqq8GNjkw11gacFmDAZGPLdNxfBgx"], + "fulfills": { + "transaction_id": "334014a29d99a488789c711b7dc5fceb534d1a9290b14d0270dbe6b60e2f036e", + "output_index": 0, + }, + "fulfillment": "pGSAIGC5nQ37hCCMAWIUBAJn4wVBOkHlURaWzWLjE5rTzG91gUBHNp8jobEyMqcIcIFl-TaAEDHRMyigDutgCIIomyVgb1a0LIk5eEpMTVP4ACxZnrVH-SIKEDHNdH4FGyBMka4B", + } + ], + "outputs": [ + { + "public_keys": ["3m1tUV5hmWPBaNQEoyFtZxFgDFiHYAYvPMzczNHwWp5v"], + "condition": { + "details": { + "type": "ed25519-sha-256", + "public_key": "3m1tUV5hmWPBaNQEoyFtZxFgDFiHYAYvPMzczNHwWp5v", + }, + "uri": "ni:///sha-256;4pXSmxViATpOG8Mcc0gYsa-4bjRnLk5MY06VXv_UeJA?fpt=ed25519-sha-256&cost=131072", + }, + "amount": "50", + }, + { + "public_keys": ["7WaJCRqUJMZjVyQxqq8GNjkw11gacFmDAZGPLdNxfBgx"], + "condition": { + "details": { + "type": "ed25519-sha-256", + "public_key": "7WaJCRqUJMZjVyQxqq8GNjkw11gacFmDAZGPLdNxfBgx", + }, + "uri": "ni:///sha-256;xtKK2YRiX7_EPF2harsf-PELcJwfHQM7jZ_YvilEOOI?fpt=ed25519-sha-256&cost=131072", + }, + "amount": "2950", + }, + ], + "operation": "TRANSFER", + "metadata": "QmTjWHzypFxE8uuXJXMJQJxgAEKjoWmQimGiutmPyJ6CAB", + "asset": {"id": "334014a29d99a488789c711b7dc5fceb534d1a9290b14d0270dbe6b60e2f036e"}, + "version": "2.0", + "id": "e577641b0e2eb619e282f802516ce043e9d4af51dd4b6c959e18246e85cae2a6", + } diff --git a/tests/db/test_planetmint_api.py b/tests/db/test_planetmint_api.py index 2711d31..e0e92eb 100644 --- a/tests/db/test_planetmint_api.py +++ b/tests/db/test_planetmint_api.py @@ -50,7 +50,6 @@ class TestBigchainApi(object): with pytest.raises(CriticalDoubleSpend): b.store_bulk_transactions([transfer_tx2]) - def test_double_inclusion(self, b, alice): from tarantool.error import DatabaseError diff --git a/tests/tendermint/test_core.py b/tests/tendermint/test_core.py index 93788d5..84d5fbd 100644 --- a/tests/tendermint/test_core.py +++ b/tests/tendermint/test_core.py @@ -411,7 +411,7 @@ def test_rollback_pre_commit_state_after_crash(b): rollback(b) for tx in txs: - assert b.get_transaction(tx.id, TARANT_TABLE_GOVERNANCE) + assert b.get_transaction(tx.id) assert b.get_latest_abci_chain() assert len(b.get_validator_set()["validators"]) == 1 assert b.get_election(migration_election.id) @@ -422,7 +422,7 @@ def test_rollback_pre_commit_state_after_crash(b): rollback(b) for tx in txs: - assert not b.get_transaction(tx.id, TARANT_TABLE_GOVERNANCE) + assert not b.get_transaction(tx.id) assert not b.get_latest_abci_chain() assert len(b.get_validator_set()["validators"]) == 4 assert len(b.get_validator_set(2)["validators"]) == 4 diff --git a/tests/tendermint/test_lib.py b/tests/tendermint/test_lib.py index a0e1b98..dc04619 100644 --- a/tests/tendermint/test_lib.py +++ b/tests/tendermint/test_lib.py @@ -170,69 +170,21 @@ def test_update_utxoset(b, signed_create_tx, signed_transfer_tx, db_conn): @pytest.mark.bdb -def test_store_transaction(mocker, b, signed_create_tx, signed_transfer_tx, db_context): - from planetmint.backend.tarantool.connection import TarantoolDBConnection - +def test_store_transaction(mocker, b, signed_create_tx, signed_transfer_tx): mocked_store_transaction = mocker.patch("planetmint.backend.query.store_transactions") b.store_bulk_transactions([signed_create_tx]) - if not isinstance(b.connection, TarantoolDBConnection): - mongo_client = MongoClient(host=db_context.host, port=db_context.port) - utxoset = mongo_client[db_context.name]["utxos"] - assert utxoset.count_documents({}) == 1 - utxo = utxoset.find_one() - assert utxo["transaction_id"] == signed_create_tx.id - assert utxo["output_index"] == 0 - - mocked_store_transaction.assert_called_once_with( - b.connection, - [signed_create_tx.to_dict()], - ) + mocked_store_transaction.assert_any_call(b.connection, [signed_create_tx.to_dict()], "transactions") mocked_store_transaction.reset_mock() b.store_bulk_transactions([signed_transfer_tx]) - if not isinstance(b.connection, TarantoolDBConnection): - assert utxoset.count_documents({}) == 1 - utxo = utxoset.find_one() - assert utxo["transaction_id"] == signed_transfer_tx.id - assert utxo["output_index"] == 0 - if not isinstance(b.connection, TarantoolDBConnection): - mocked_store_transaction.assert_called_once_with( - b.connection, - [signed_transfer_tx.to_dict()], - ) @pytest.mark.bdb -def test_store_bulk_transaction(mocker, b, signed_create_tx, signed_transfer_tx, db_context): - from planetmint.backend.tarantool.connection import TarantoolDBConnection - +def test_store_bulk_transaction(mocker, b, signed_create_tx, signed_transfer_tx): mocked_store_transactions = mocker.patch("planetmint.backend.query.store_transactions") b.store_bulk_transactions((signed_create_tx,)) - if not isinstance(b.connection, TarantoolDBConnection): - mongo_client = MongoClient(host=db_context.host, port=db_context.port) - utxoset = mongo_client[db_context.name]["utxos"] - assert utxoset.count_documents({}) == 1 - utxo = utxoset.find_one() - assert utxo["transaction_id"] == signed_create_tx.id - assert utxo["output_index"] == 0 - - mocked_store_transactions.assert_called_once_with( - b.connection, - [signed_create_tx.to_dict()], - ) - + mocked_store_transactions.assert_any_call(b.connection, [signed_create_tx.to_dict()], "transactions") mocked_store_transactions.reset_mock() b.store_bulk_transactions((signed_transfer_tx,)) - if not isinstance(b.connection, TarantoolDBConnection): - assert utxoset.count_documents({}) == 1 - utxo = utxoset.find_one() - assert utxo["transaction_id"] == signed_transfer_tx.id - assert utxo["output_index"] == 0 - - if not isinstance(b.connection, TarantoolDBConnection): - mocked_store_transactions.assert_called_once_with( - b.connection, - [signed_transfer_tx.to_dict()], - ) @pytest.mark.bdb diff --git a/tests/test_core.py b/tests/test_core.py index 73f6778..dc1d5e4 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -89,7 +89,7 @@ def test_get_spent_issue_1271(b, alice, bob, carol): assert b.validate_transaction(tx_5) b.store_bulk_transactions([tx_5]) - assert b.get_spent(tx_2.id, 0) == tx_5.to_dict() + assert b.get_spent(tx_2.id, 0) == tx_5.to_dict() assert not b.get_spent(tx_5.id, 0) assert b.get_outputs_filtered(alice.public_key) assert b.get_outputs_filtered(alice.public_key, spent=False) diff --git a/tests/upsert_validator/test_upsert_validator_vote.py b/tests/upsert_validator/test_upsert_validator_vote.py index faad666..cac3c78 100644 --- a/tests/upsert_validator/test_upsert_validator_vote.py +++ b/tests/upsert_validator/test_upsert_validator_vote.py @@ -248,7 +248,7 @@ def test_upsert_validator(b, node_key, node_keys, ed25519_node_keys): ) code, message = b.write_transaction(election, BROADCAST_TX_COMMIT) assert code == 202 - assert b.get_transaction(election.id, TARANT_TABLE_GOVERNANCE) + assert b.get_transaction(election.id) tx_vote = gen_vote(election, 0, ed25519_node_keys) assert b.validate_transaction(tx_vote) diff --git a/tests/utils.py b/tests/utils.py index 8dbdc67..3fb951f 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -10,7 +10,7 @@ import random from functools import singledispatch from planetmint.backend.localmongodb.connection import LocalMongoDBConnection from planetmint.backend.tarantool.connection import TarantoolDBConnection -from planetmint.backend.schema import TABLES, SPACE_NAMES +from planetmint.backend.schema import TABLES from transactions.common import crypto from transactions.common.transaction_mode_types import BROADCAST_TX_COMMIT from transactions.types.assets.create import Create @@ -40,7 +40,9 @@ def generate_block(planet): from transactions.common.crypto import generate_key_pair alice = generate_key_pair() - tx = Create.generate([alice.public_key], [([alice.public_key], 1)], assets=[{"data":None}]).sign([alice.private_key]) + tx = Create.generate([alice.public_key], [([alice.public_key], 1)], assets=[{"data": None}]).sign( + [alice.private_key] + ) code, message = planet.write_transaction(tx, BROADCAST_TX_COMMIT) assert code == 202 diff --git a/tox.ini b/tox.ini deleted file mode 100644 index 853028d..0000000 --- a/tox.ini +++ /dev/null @@ -1,31 +0,0 @@ -[tox] -skipsdist = true -envlist = py{39}, docsroot - -[gh-actions] -python = - 3.9 = docsroot - -[base] -basepython = python3.9 -deps = pip>=9.0.1 - -[testenv] -usedevelop = True -setenv = - PYTHONPATH={toxinidir}:{toxinidir}/planetmint -deps = {[base]deps} -install_command = pip install {opts} {packages} -extras = test -commands = pytest -v -n auto --cov=planetmint --basetemp={envtmpdir} - -[testenv:docsroot] -basepython = {[base]basepython} -changedir = docs/root/source -deps = - {[base]deps} - typing-extensions - -r{toxinidir}/docs/root/requirements.txt -extras = None -commands = sphinx-build -b html -d {envtmpdir}/doctrees . {envtmpdir}/html -