removed fastquery class

Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com>
This commit is contained in:
Lorenz Herzberger 2023-04-09 11:49:48 +02:00
parent 9cf743f42c
commit 921e604724
No known key found for this signature in database
GPG Key ID: FA5EE906EB55316A
5 changed files with 6 additions and 200 deletions

View File

@ -447,6 +447,7 @@ def get_outputs_by_tx_id(connection, tx_id: str) -> list[Output]:
"""Retrieve outputs for a transaction by its id"""
raise NotImplementedError
@singledispatch
def get_outputs_by_owner(connection, public_key: str, table: str) -> list[Output]:
"""Retrieve an owners outputs by public key"""

View File

@ -513,4 +513,4 @@ def get_latest_abci_chain(connection) -> Union[dict, None]:
@catch_db_exception
def get_outputs_by_owner(connection, public_key: str, table=TARANT_TABLE_OUTPUT) -> list[Output]:
outputs = connection.connect().select(table, public_key, index="public_keys")
return [Output.from_tuple(output) for output in outputs]
return [Output.from_tuple(output) for output in outputs]

View File

@ -9,7 +9,6 @@ from transactions.common.exceptions import InputDoesNotExist
from planetmint import config_utils, backend
from planetmint.const import GOVERNANCE_TRANSACTION_TYPES
from planetmint.model.fastquery import FastQuery
from planetmint.abci.utils import key_from_base64, merkleroot
from planetmint.backend.connection import Connection
from planetmint.backend.tarantool.const import (
@ -87,7 +86,10 @@ class DataAccessor:
elif spent is True:
spent_outputs = []
for output in outputs:
if not any(utxo.transaction_id == output.transaction_id and utxo.index == output.index for utxo in unspent_outputs):
if not any(
utxo.transaction_id == output.transaction_id and utxo.index == output.index
for utxo in unspent_outputs
):
spent_outputs.append(output)
return unspent_outputs
elif spent is False:
@ -340,7 +342,3 @@ class DataAccessor:
# TODO Notice the sorted call!
return merkleroot(sorted(hashes))
@property
def fastquery(self):
return FastQuery(self.connection)

View File

@ -1,76 +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
from planetmint.backend import query
from transactions.common.transaction import TransactionLink
from planetmint.backend.models.output import ConditionDetails
class FastQuery:
"""Database queries that join on block results from a single node."""
def __init__(self, connection):
self.connection = connection
def get_outputs_by_public_key(self, public_key):
"""Get outputs for a public key"""
txs = query.get_owned_ids(self.connection, public_key)
return [
TransactionLink(tx.id, index)
for tx in txs
for index, output in enumerate(tx.outputs)
if condition_details_has_owner(output.condition.details, public_key)
]
def filter_spent_outputs(self, outputs):
"""Remove outputs that have been spent
Args:
outputs: list of TransactionLink
"""
links = [o.to_dict() for o in outputs]
txs = query.get_spending_transactions(self.connection, links)
spends = {TransactionLink.from_dict(input.fulfills.to_dict()) for tx in txs for input in tx.inputs}
return [ff for ff in outputs if ff not in spends]
def filter_unspent_outputs(self, outputs):
"""Remove outputs that have not been spent
Args:
outputs: list of TransactionLink
"""
links = [o.to_dict() for o in outputs]
txs = query.get_spending_transactions(self.connection, links)
spends = {TransactionLink.from_dict(input.fulfills.to_dict()) for tx in txs for input in tx.inputs}
return [ff for ff in outputs if ff in spends]
# TODO: Rename this function, it's handling fulfillments not conditions
def condition_details_has_owner(condition_details, owner):
"""Check if the public_key of owner is in the condition details
as an Ed25519Fulfillment.public_key
Args:
condition_details (dict): dict with condition details
owner (str): base58 public key of owner
Returns:
bool: True if the public key is found in the condition details, False otherwise
"""
if isinstance(condition_details, ConditionDetails) and condition_details.sub_conditions is not None:
result = condition_details_has_owner(condition_details.sub_conditions, owner)
if result:
return True
elif isinstance(condition_details, list):
for subcondition in condition_details:
result = condition_details_has_owner(subcondition, owner)
if result:
return True
else:
if condition_details.public_key is not None and owner == condition_details.public_key:
return True
return False

View File

@ -1,117 +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
import pytest
from transactions.common.transaction import TransactionLink
from transactions.types.assets.create import Create
from transactions.types.assets.transfer import Transfer
pytestmark = pytest.mark.bdb
@pytest.fixture
def txns(b, user_pk, user_sk, user2_pk, user2_sk, test_models):
txs = [
Create.generate([user_pk], [([user2_pk], 1)]).sign([user_sk]),
Create.generate([user2_pk], [([user_pk], 1)]).sign([user2_sk]),
Create.generate([user_pk], [([user_pk], 1), ([user2_pk], 1)]).sign([user_sk]),
]
b.models.store_bulk_transactions(txs)
return txs
def test_get_outputs_by_public_key(b, user_pk, user2_pk, txns, test_models):
expected = [TransactionLink(txns[1].id, 0), TransactionLink(txns[2].id, 0)]
actual = test_models.fastquery.get_outputs_by_public_key(user_pk)
_all_txs = set([tx.txid for tx in expected + actual])
assert len(_all_txs) == 2
# assert b.models.fastquery.get_outputs_by_public_key(user_pk) == [ # OLD VERIFICATION
# TransactionLink(txns[1].id, 0),
# TransactionLink(txns[2].id, 0)
# ]
actual_1 = test_models.fastquery.get_outputs_by_public_key(user2_pk)
expected_1 = [
TransactionLink(txns[0].id, 0),
TransactionLink(txns[2].id, 1),
]
_all_tx_1 = set([tx.txid for tx in actual_1 + expected_1])
assert len(_all_tx_1) == 2
# assert b.models.fastquery.get_outputs_by_public_key(user2_pk) == [ # OLD VERIFICATION
# TransactionLink(txns[0].id, 0),
# TransactionLink(txns[2].id, 1),
# ]
def test_filter_spent_outputs(b, user_pk, user_sk, test_models):
out = [([user_pk], 1)]
tx1 = Create.generate([user_pk], out * 2)
tx1.sign([user_sk])
inputs = tx1.to_inputs()
tx2 = Transfer.generate([inputs[0]], out, [tx1.id])
tx2.sign([user_sk])
# tx2 produces a new unspent. inputs[1] remains unspent.
b.models.store_bulk_transactions([tx1, tx2])
outputs = test_models.fastquery.get_outputs_by_public_key(user_pk)
unspents = test_models.fastquery.filter_spent_outputs(outputs)
assert set(unsp for unsp in unspents) == {
inputs[1].fulfills,
tx2.to_inputs()[0].fulfills,
}
def test_filter_unspent_outputs(b, user_pk, user_sk, test_models):
out = [([user_pk], 1)]
tx1 = Create.generate([user_pk], out * 2)
tx1.sign([user_sk])
inputs = tx1.to_inputs()
tx2 = Transfer.generate([inputs[0]], out, [tx1.id])
tx2.sign([user_sk])
# tx2 produces a new unspent. input[1] remains unspent.
b.models.store_bulk_transactions([tx1, tx2])
outputs = test_models.fastquery.get_outputs_by_public_key(user_pk)
spents = test_models.fastquery.filter_unspent_outputs(outputs)
assert set(sp for sp in spents) == {
inputs[0].fulfills,
}
def test_outputs_query_key_order(b, user_pk, user_sk, user2_pk, test_validator):
tx1 = Create.generate([user_pk], [([user_pk], 3), ([user_pk], 2), ([user_pk], 1)]).sign([user_sk])
b.models.store_bulk_transactions([tx1])
inputs = tx1.to_inputs()
tx2 = Transfer.generate([inputs[1]], [([user2_pk], 2)], [tx1.id]).sign([user_sk])
assert test_validator.validate_transaction(tx2)
b.models.store_bulk_transactions([tx2])
outputs = b.models.get_outputs_filtered(user_pk, spent=False)
assert len(outputs) == 2
outputs = b.models.get_outputs_filtered(user2_pk, spent=False)
assert len(outputs) == 1
# clean the transaction, metdata and asset collection
b.models.delete_transactions([tx1.id, tx2.id])
b.models.store_bulk_transactions([tx1, tx2])
outputs = b.models.get_outputs_filtered(user_pk, spent=False)
assert len(outputs) == 2
outputs = b.models.get_outputs_filtered(user2_pk, spent=False)
assert len(outputs) == 1