mirror of
https://github.com/planetmint/planetmint.git
synced 2025-11-24 14:35:45 +00:00
Merge branch 'refactor-backend' into simplified_unit_tests
This commit is contained in:
commit
08b2924679
35
.github/workflows/documenation.yml
vendored
35
.github/workflows/documenation.yml
vendored
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -53,7 +53,6 @@ pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
|
||||
10
CHANGELOG.md
10
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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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',
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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"
|
||||
}]
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
GET /api/v1/transactions/61e1312b80705e0dabb948c9d78dae7f62d64832abda822b13d89c4a7305d4ac HTTP/1.1
|
||||
GET /api/v1/transactions/0fdeb547670bbea980389df53cf5a91e60159339084c6b0b5cc0b5494a679530 HTTP/1.1
|
||||
Host: example.com
|
||||
|
||||
|
||||
@ -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"
|
||||
}
|
||||
|
||||
@ -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"
|
||||
}
|
||||
|
||||
@ -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"
|
||||
}
|
||||
|
||||
@ -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"
|
||||
}
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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
|
||||
@ -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__)
|
||||
|
||||
|
||||
@ -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"
|
||||
|
||||
|
||||
@ -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()
|
||||
@ -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]
|
||||
|
||||
@ -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):
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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"]
|
||||
|
||||
@ -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:
|
||||
|
||||
3
setup.py
3
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(
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 = []
|
||||
|
||||
@ -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):
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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",
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
31
tox.ini
31
tox.ini
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user