mirror of
https://github.com/planetmint/planetmint.git
synced 2025-11-24 22:45:44 +00:00
Fix recursion error
This commit is contained in:
parent
50ca7982ed
commit
3ebfed41c7
@ -7,6 +7,9 @@ from __future__ import annotations
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Optional
|
||||
|
||||
from planetmint.backend.models import Asset, MetaData, Input, Output, Script
|
||||
from planetmint.backend.models.keys import Keys
|
||||
|
||||
|
||||
@dataclass
|
||||
class Transaction:
|
||||
@ -14,6 +17,12 @@ class Transaction:
|
||||
operation: str = ""
|
||||
version: str = ""
|
||||
raw_transaction: dict = dict
|
||||
assets: list[Asset] = None
|
||||
metadata: MetaData = None
|
||||
inputs: list[Input] = None
|
||||
outputs: list[Output] = None
|
||||
keys: Keys = None
|
||||
script: Script = None
|
||||
|
||||
@staticmethod
|
||||
def from_dict(transaction: dict) -> Transaction:
|
||||
@ -21,6 +30,7 @@ class Transaction:
|
||||
id=transaction["id"],
|
||||
operation=transaction["operation"],
|
||||
version=transaction["version"],
|
||||
inputs=transaction["inputs"],
|
||||
raw_transaction=transaction["transaction"],
|
||||
)
|
||||
|
||||
|
||||
@ -68,12 +68,25 @@ def store_transaction(connection, transaction):
|
||||
|
||||
|
||||
@singledispatch
|
||||
def get_transaction(connection, transaction_id):
|
||||
"""Get a transaction from the database."""
|
||||
def get_transaction_space_by_id(connection, transaction_id):
|
||||
"""Get the transaction space by transaction id."""
|
||||
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
@singledispatch
|
||||
def get_transaction_single(connection, transaction_id):
|
||||
"""Get a single transaction by id."""
|
||||
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
@singledispatch
|
||||
def get_transaction(connection, transaction_id):
|
||||
"""Get a transaction by id."""
|
||||
|
||||
raise NotImplementedError
|
||||
|
||||
@singledispatch
|
||||
def get_transactions(connection, transactions_ids) -> list[Transaction]:
|
||||
"""Get a transaction from the transactions table.
|
||||
|
||||
@ -34,26 +34,16 @@ register_query = module_dispatch_registrar(query)
|
||||
def _group_transaction_by_ids(connection, txids: list):
|
||||
_transactions = []
|
||||
for txid in txids:
|
||||
tx = get_transaction(connection, txid)
|
||||
tx = get_transaction_space_by_id(connection, txid)
|
||||
if tx is None:
|
||||
continue
|
||||
|
||||
_txinputs = get_inputs_by_tx_id(connection, txid)
|
||||
_txoutputs = get_outputs_by_tx_id(connection, txid)
|
||||
_txkeys = get_keys_by_tx_id(connection, txid)
|
||||
_txassets = get_assets_by_tx_id(connection, txid)
|
||||
_txmeta = get_metadata_by_tx_id(connection, txid)
|
||||
_txscript = get_script_by_tx_id(connection, txid)
|
||||
|
||||
tx = {
|
||||
TARANT_TABLE_TRANSACTION: tx,
|
||||
TARANT_TABLE_INPUT: [tx_input.to_dict() for tx_input in _txinputs],
|
||||
TARANT_TABLE_OUTPUT: [output.to_dict() for output in _txoutputs],
|
||||
TARANT_TABLE_KEYS: [key.to_dict() for key in _txkeys],
|
||||
TARANT_TABLE_ASSETS: _txassets,
|
||||
TARANT_TABLE_META_DATA: _txmeta,
|
||||
TARANT_TABLE_SCRIPT: _txscript.script if _txscript else None,
|
||||
}
|
||||
tx.inputs = get_inputs_by_tx_id(connection, txid)
|
||||
tx.outputs = get_outputs_by_tx_id(connection, txid)
|
||||
tx.keys = get_keys_by_tx_id(connection, txid)
|
||||
tx.assets = get_assets_by_tx_id(connection, txid)
|
||||
tx.metadata = get_metadata_by_tx_id(connection, txid)
|
||||
tx.script = get_script_by_tx_id(connection, txid)
|
||||
|
||||
_transactions.append(tx)
|
||||
return _transactions
|
||||
@ -80,6 +70,10 @@ def get_keys_by_tx_id(connection, tx_id: str) -> list[Keys]:
|
||||
return [Keys.from_tuple(key) for key in _sorted_keys]
|
||||
|
||||
|
||||
@register_query(TarantoolDBConnection)
|
||||
def get_transaction(connection, tx_id: str) -> Transaction:
|
||||
return NotImplemented
|
||||
|
||||
@register_query(TarantoolDBConnection)
|
||||
def store_transaction_inputs(connection, input: Input, index: int):
|
||||
connection.run(
|
||||
@ -180,17 +174,21 @@ def store_transaction(connection, transaction):
|
||||
|
||||
|
||||
@register_query(TarantoolDBConnection)
|
||||
def get_transaction(connection, transaction_id):
|
||||
def get_transaction_space_by_id(connection, transaction_id):
|
||||
txs = connection.run(connection.space(TARANT_TABLE_TRANSACTION).select(transaction_id, index=TARANT_ID_SEARCH))
|
||||
if len(txs) == 0:
|
||||
return None
|
||||
return Transaction.from_tuple(txs[0])
|
||||
|
||||
|
||||
@register_query(TarantoolDBConnection)
|
||||
def get_transaction_single(connection, transaction_id):
|
||||
return _group_transaction_by_ids(txids=[transaction_id], connection=connection)
|
||||
|
||||
|
||||
@register_query(TarantoolDBConnection)
|
||||
def get_transactions(connection, transactions_ids: list) -> list[Transaction]:
|
||||
_transactions = _group_transaction_by_ids(txids=transactions_ids, connection=connection)
|
||||
return [Transaction.from_tuple(_transaction) for _transaction in _transactions]
|
||||
return _group_transaction_by_ids(txids=transactions_ids, connection=connection)
|
||||
|
||||
|
||||
@register_query(TarantoolDBConnection)
|
||||
@ -276,8 +274,7 @@ def get_spent(connection, fullfil_transaction_id: str, fullfil_output_index: str
|
||||
[fullfil_transaction_id, str(fullfil_output_index)], index="spent_search"
|
||||
)
|
||||
)
|
||||
_transactions = _group_transaction_by_ids(txids=[inp[0] for inp in _inputs], connection=connection)
|
||||
return _transactions
|
||||
return _group_transaction_by_ids(txids=[inp[0] for inp in _inputs], connection=connection)
|
||||
|
||||
|
||||
@register_query(TarantoolDBConnection)
|
||||
@ -371,8 +368,7 @@ def get_owned_ids(connection, owner: str):
|
||||
if _keys is None or len(_keys) == 0:
|
||||
return []
|
||||
_transactionids = list(set([key[1] for key in _keys]))
|
||||
_transactions = _group_transaction_by_ids(txids=_transactionids, connection=connection)
|
||||
return _transactions
|
||||
return _group_transaction_by_ids(txids=_transactionids, connection=connection)
|
||||
|
||||
|
||||
@register_query(TarantoolDBConnection)
|
||||
@ -579,8 +575,7 @@ def get_asset_tokens_for_public_key(
|
||||
_transactions = connection.run(connection.space(TARANT_TABLE_ASSETS).select([asset_id], index="assetid_search"))
|
||||
# _transactions = _transactions
|
||||
# _keys = _keys.data
|
||||
_grouped_transactions = _group_transaction_by_ids(connection=connection, txids=[_tx[1] for _tx in _transactions])
|
||||
return _grouped_transactions
|
||||
return _group_transaction_by_ids(connection=connection, txids=[_tx[1] for _tx in _transactions])
|
||||
|
||||
|
||||
@register_query(TarantoolDBConnection)
|
||||
|
||||
@ -193,7 +193,7 @@ def run_election_approve(args, planet):
|
||||
"""
|
||||
|
||||
key = load_node_key(args.sk)
|
||||
tx = planet.get_transaction(args.election_id)
|
||||
tx = planet.get_transaction_space_by_id(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]
|
||||
@ -226,7 +226,7 @@ def run_election_show(args, planet):
|
||||
:param planet: an instance of Planetmint
|
||||
"""
|
||||
|
||||
election = planet.get_transaction(args.election_id)
|
||||
election = planet.get_transaction_space_by_id(args.election_id)
|
||||
if not election:
|
||||
logger.error(f"No election found with election_id {args.election_id}")
|
||||
return
|
||||
|
||||
@ -742,23 +742,23 @@ class Planetmint(object):
|
||||
# validators and their voting power in the network
|
||||
return current_topology == voters
|
||||
|
||||
def count_votes(self, election_pk, transactions, getter=getattr):
|
||||
def count_votes(self, election_pk, transactions):
|
||||
votes = 0
|
||||
for txn in transactions:
|
||||
if getter(txn, "operation") == Vote.OPERATION:
|
||||
for output in getter(txn, "outputs"):
|
||||
if txn.operation == Vote.OPERATION:
|
||||
for output in txn.outputs:
|
||||
# NOTE: We enforce that a valid vote to election id will have only
|
||||
# election_pk in the output public keys, including any other public key
|
||||
# along with election_pk will lead to vote being not considered valid.
|
||||
if len(getter(output, "public_keys")) == 1 and [election_pk] == getter(output, "public_keys"):
|
||||
votes = votes + int(getter(output, "amount"))
|
||||
if len(output.public_keys) == 1 and [election_pk] == output.public_keys:
|
||||
votes = votes + output.amount
|
||||
return votes
|
||||
|
||||
def get_commited_votes(self, transaction, election_pk=None): # TODO: move somewhere else
|
||||
if election_pk is None:
|
||||
election_pk = election_id_to_public_key(transaction.id)
|
||||
txns = list(backend.query.get_asset_tokens_for_public_key(self.connection, transaction.id, election_pk))
|
||||
return self.count_votes(election_pk, txns, dict.get)
|
||||
return self.count_votes(election_pk, txns)
|
||||
|
||||
def _get_initiated_elections(self, height, txns): # TODO: move somewhere else
|
||||
elections = []
|
||||
|
||||
@ -37,7 +37,7 @@ class TransactionApi(Resource):
|
||||
pool = current_app.config["bigchain_pool"]
|
||||
|
||||
with pool() as planet:
|
||||
tx = planet.get_transaction(tx_id)
|
||||
tx = planet.get_transaction_space_by_id(tx_id)
|
||||
|
||||
if not tx:
|
||||
return make_error(404)
|
||||
|
||||
@ -320,7 +320,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)
|
||||
assert b.get_transaction_space_by_id(election_id)
|
||||
|
||||
|
||||
@pytest.mark.bdb
|
||||
@ -347,7 +347,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)
|
||||
assert b.get_transaction_space_by_id(election_id)
|
||||
|
||||
|
||||
@pytest.mark.abci
|
||||
@ -358,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)
|
||||
assert b.get_transaction_space_by_id(election_id)
|
||||
|
||||
|
||||
@pytest.mark.bdb
|
||||
@ -377,7 +377,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)
|
||||
assert b.get_transaction_space_by_id(election_id)
|
||||
|
||||
|
||||
@pytest.mark.bdb
|
||||
@ -446,7 +446,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)
|
||||
assert b.get_transaction_space_by_id(approve)
|
||||
|
||||
|
||||
@pytest.mark.bdb
|
||||
@ -463,7 +463,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)
|
||||
assert b.get_transaction_space_by_id(approval_id)
|
||||
|
||||
|
||||
@pytest.mark.bdb
|
||||
|
||||
@ -105,7 +105,7 @@ class TestBigchainApi(object):
|
||||
tx = Create.generate([alice.public_key], [([alice.public_key], 1)], assets=[asset1]).sign([alice.private_key])
|
||||
b.store_bulk_transactions([tx])
|
||||
|
||||
tx_from_db = b.get_transaction(tx.id)
|
||||
tx_from_db = b.get_transaction_space_by_id(tx.id)
|
||||
|
||||
before = tx.to_dict()
|
||||
after = tx_from_db.to_dict()
|
||||
@ -131,7 +131,7 @@ class TestTransactionValidation(object):
|
||||
from transactions.common.exceptions import InvalidSignature
|
||||
|
||||
input_tx = b.fastquery.get_outputs_by_public_key(user_pk).pop()
|
||||
input_transaction = b.get_transaction(input_tx.txid)
|
||||
input_transaction = b.get_transaction_space_by_id(input_tx.txid)
|
||||
sk, pk = generate_key_pair()
|
||||
tx = Create.generate([pk], [([user_pk], 1)])
|
||||
tx.operation = "TRANSFER"
|
||||
@ -158,7 +158,7 @@ class TestMultipleInputs(object):
|
||||
user2_sk, user2_pk = crypto.generate_key_pair()
|
||||
|
||||
tx_link = b.fastquery.get_outputs_by_public_key(user_pk).pop()
|
||||
input_tx = b.get_transaction(tx_link.txid)
|
||||
input_tx = b.get_transaction_space_by_id(tx_link.txid)
|
||||
inputs = input_tx.to_inputs()
|
||||
tx = Transfer.generate(inputs, [([user2_pk], 1)], asset_ids=[input_tx.id])
|
||||
tx = tx.sign([user_sk])
|
||||
@ -175,7 +175,7 @@ class TestMultipleInputs(object):
|
||||
user3_sk, user3_pk = crypto.generate_key_pair()
|
||||
tx_link = b.fastquery.get_outputs_by_public_key(user_pk).pop()
|
||||
|
||||
input_tx = b.get_transaction(tx_link.txid)
|
||||
input_tx = b.get_transaction_space_by_id(tx_link.txid)
|
||||
tx = Transfer.generate(input_tx.to_inputs(), [([user2_pk, user3_pk], 1)], asset_ids=[input_tx.id])
|
||||
tx = tx.sign([user_sk])
|
||||
|
||||
@ -195,7 +195,7 @@ class TestMultipleInputs(object):
|
||||
b.store_bulk_transactions([tx])
|
||||
|
||||
owned_input = b.fastquery.get_outputs_by_public_key(user_pk).pop()
|
||||
input_tx = b.get_transaction(owned_input.txid)
|
||||
input_tx = b.get_transaction_space_by_id(owned_input.txid)
|
||||
inputs = input_tx.to_inputs()
|
||||
|
||||
transfer_tx = Transfer.generate(inputs, [([user3_pk], 1)], asset_ids=[input_tx.id])
|
||||
@ -220,7 +220,7 @@ class TestMultipleInputs(object):
|
||||
|
||||
# get input
|
||||
tx_link = b.fastquery.get_outputs_by_public_key(user_pk).pop()
|
||||
tx_input = b.get_transaction(tx_link.txid)
|
||||
tx_input = b.get_transaction_space_by_id(tx_link.txid)
|
||||
|
||||
tx = Transfer.generate(tx_input.to_inputs(), [([user3_pk, user4_pk], 1)], asset_ids=[tx_input.id])
|
||||
tx = tx.sign([user_sk, user2_sk])
|
||||
|
||||
@ -235,7 +235,7 @@ def test_deliver_tx__valid_create_updates_db_and_emits_event(b, init_chain_reque
|
||||
|
||||
app.end_block(types.RequestEndBlock(height=99))
|
||||
app.commit()
|
||||
assert b.get_transaction(tx.id).id == tx.id
|
||||
assert b.get_transaction_space_by_id(tx.id).id == tx.id
|
||||
block_event = events.get()
|
||||
assert block_event.data["transactions"] == [tx]
|
||||
|
||||
@ -264,7 +264,7 @@ def test_deliver_tx__double_spend_fails(b, init_chain_request):
|
||||
|
||||
app.end_block(types.RequestEndBlock(height=99))
|
||||
app.commit()
|
||||
assert b.get_transaction(tx.id).id == tx.id
|
||||
assert b.get_transaction_space_by_id(tx.id).id == tx.id
|
||||
result = app.deliver_tx(encode_tx_to_bytes(tx))
|
||||
assert result.code == CodeTypeError
|
||||
|
||||
@ -410,7 +410,7 @@ def test_rollback_pre_commit_state_after_crash(b):
|
||||
rollback(b)
|
||||
|
||||
for tx in txs:
|
||||
assert b.get_transaction(tx.id)
|
||||
assert b.get_transaction_space_by_id(tx.id)
|
||||
assert b.get_latest_abci_chain()
|
||||
assert len(b.get_validator_set()["validators"]) == 1
|
||||
assert b.get_election(migration_election.id)
|
||||
@ -421,7 +421,7 @@ def test_rollback_pre_commit_state_after_crash(b):
|
||||
rollback(b)
|
||||
|
||||
for tx in txs:
|
||||
assert not b.get_transaction(tx.id)
|
||||
assert not b.get_transaction_space_by_id(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
|
||||
|
||||
@ -78,7 +78,7 @@ def test_app(b, eventqueue_fixture, init_chain_request):
|
||||
data = p.process("commit", None)
|
||||
res = next(read_messages(BytesIO(data), types.Response))
|
||||
assert res.commit.data == new_block_hash.encode("utf-8")
|
||||
assert b.get_transaction(tx.id).id == tx.id
|
||||
assert b.get_transaction_space_by_id(tx.id).id == tx.id
|
||||
|
||||
block0 = b.get_latest_block()
|
||||
assert block0
|
||||
|
||||
@ -69,7 +69,7 @@ def test_asset_is_separated_from_transaciton(b):
|
||||
b.store_bulk_transactions([tx])
|
||||
assert "asset" not in backend.query.get_transaction(b.connection, tx.id)
|
||||
assert backend.query.get_asset(b.connection, tx.id)["data"] == assets[0]
|
||||
assert b.get_transaction(tx.id).to_dict() == tx_dict
|
||||
assert b.get_transaction_space_by_id(tx.id).to_dict() == tx_dict
|
||||
|
||||
|
||||
@pytest.mark.bdb
|
||||
|
||||
@ -246,7 +246,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)
|
||||
assert b.get_transaction_space_by_id(election.id)
|
||||
|
||||
tx_vote = gen_vote(election, 0, ed25519_node_keys)
|
||||
assert b.validate_transaction(tx_vote)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user