From f65cb049e843679736541f74e9302291bdeebc91 Mon Sep 17 00:00:00 2001 From: andrei Date: Tue, 10 May 2022 14:39:55 +0300 Subject: [PATCH] store and get utxo fixed --- planetmint/backend/tarantool/init.lua | 2 +- planetmint/backend/tarantool/query.py | 10 ++-- tests/conftest.py | 3 +- tests/tendermint/test_lib.py | 73 +++++++++++++++------------ 4 files changed, 48 insertions(+), 40 deletions(-) diff --git a/planetmint/backend/tarantool/init.lua b/planetmint/backend/tarantool/init.lua index b6cb246..92752e7 100644 --- a/planetmint/backend/tarantool/init.lua +++ b/planetmint/backend/tarantool/init.lua @@ -64,7 +64,7 @@ keys:create_index('txid_search', {type = 'tree', unique=false, parts={'transacti keys:create_index('output_search', {type = 'tree', unique=false, parts={'output_id'}}) utxos = box.schema.space.create('utxos', {engine = 'memtx' , is_sync = false}) -utxos:format({{name='transaction_id' , type='string'}, {name='output_index' , type='integer'}}) +utxos:format({{name='transaction_id' , type='string'}, {name='output_index' , type='integer'}, {name='utxo_dict', type='string'}}) utxos:create_index('id_search', {type='hash' , parts={'transaction_id', 'output_index'}}) utxos:create_index('transaction_search', {type='tree', unique=false, parts={'transaction_id'}}) utxos:create_index('index_search', {type='tree', unique=false, parts={'output_index'}}) \ No newline at end of file diff --git a/planetmint/backend/tarantool/query.py b/planetmint/backend/tarantool/query.py index 5ba5f19..23528b3 100644 --- a/planetmint/backend/tarantool/query.py +++ b/planetmint/backend/tarantool/query.py @@ -9,11 +9,10 @@ from secrets import token_hex from operator import itemgetter from planetmint.backend import query -from planetmint.backend.exceptions import DuplicateKeyError -from planetmint.backend.exceptions import OperationError from planetmint.backend.utils import module_dispatch_registrar from planetmint.backend.tarantool.connection import TarantoolDB from planetmint.backend.tarantool.transaction.tools import TransactionCompose, TransactionDecompose +from json import dumps, loads register_query = module_dispatch_registrar(query) @@ -337,7 +336,7 @@ def store_unspent_outputs(connection, *unspent_outputs: list): space = connection.space('utxos') if unspent_outputs: for utxo in unspent_outputs: - space.insert((utxo['transaction_id'], utxo['output_index'])) + space.insert((utxo['transaction_id'], utxo['output_index'], dumps(utxo))) @register_query(TarantoolDB) @@ -349,9 +348,10 @@ def delete_unspent_outputs(connection, *unspent_outputs: list): @register_query(TarantoolDB) -def get_unspent_outputs(connection): +def get_unspent_outputs(connection, query=None): # for now we don't have implementation for 'query'. space = connection.space('utxos') - return space.select() + _utxos = space.select([]).data + return [loads(utx[2]) for utx in _utxos] @register_query(TarantoolDB) diff --git a/tests/conftest.py b/tests/conftest.py index 1e4d54a..d416f77 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -540,8 +540,9 @@ def dummy_unspent_outputs(): @pytest.fixture def utxoset(dummy_unspent_outputs, utxo_collection): + from json import dumps for utxo in dummy_unspent_outputs: - res = utxo_collection.insert((utxo["transaction_id"], utxo["output_index"])) + res = utxo_collection.insert((utxo["transaction_id"], utxo["output_index"], dumps(utxo))) assert res assert len(utxo_collection.select()) == 3 return dummy_unspent_outputs, utxo_collection diff --git a/tests/tendermint/test_lib.py b/tests/tendermint/test_lib.py index bb76071..727b3e7 100644 --- a/tests/tendermint/test_lib.py +++ b/tests/tendermint/test_lib.py @@ -7,7 +7,6 @@ from operator import index import os from unittest.mock import patch - try: from hashlib import sha3_256 except ImportError: @@ -45,8 +44,8 @@ def test_asset_is_separated_from_transaciton(b): tx = Transaction.create([alice.public_key], [([bob.public_key], 1)], metadata=None, - asset=asset)\ - .sign([alice.private_key]) + asset=asset) \ + .sign([alice.private_key]) # with store_bulk_transactions we use `insert_many` where PyMongo # automatically adds an `_id` field to the tx, therefore we need the @@ -89,8 +88,8 @@ def test_validation_error(b): alice = generate_key_pair() tx = Transaction.create([alice.public_key], [([alice.public_key], 1)], - asset=None)\ - .sign([alice.private_key]).to_dict() + asset=None) \ + .sign([alice.private_key]).to_dict() tx['metadata'] = '' assert not b.validate_transaction(tx) @@ -105,8 +104,8 @@ def test_write_and_post_transaction(mock_post, b): alice = generate_key_pair() tx = Transaction.create([alice.public_key], [([alice.public_key], 1)], - asset=None)\ - .sign([alice.private_key]).to_dict() + asset=None) \ + .sign([alice.private_key]).to_dict() tx = b.validate_transaction(tx) b.write_transaction(tx, BROADCAST_TX_ASYNC) @@ -195,7 +194,7 @@ def test_store_transaction(mocker, b, signed_create_tx, mocked_store_transaction.assert_called_once_with( b.connection, [{k: v for k, v in signed_create_tx.to_dict().items() - if k not in ('asset', 'metadata')}], + if k not in ('asset', 'metadata')}], ) mocked_store_asset.reset_mock() mocked_store_metadata.reset_mock() @@ -213,13 +212,14 @@ def test_store_transaction(mocker, b, signed_create_tx, mocked_store_transaction.assert_called_once_with( b.connection, [{k: v for k, v in signed_transfer_tx.to_dict().items() - if k != 'metadata'}], + if k != 'metadata'}], ) @pytest.mark.bdb def test_store_bulk_transaction(mocker, b, signed_create_tx, signed_transfer_tx, db_context): + from planetmint.backend.tarantool.connection import TarantoolDB mocked_store_assets = mocker.patch( 'planetmint.backend.query.store_assets') mocked_store_metadata = mocker.patch( @@ -233,10 +233,16 @@ def test_store_bulk_transaction(mocker, b, signed_create_tx, # utxo = utxoset.find_one() # assert utxo['transaction_id'] == signed_create_tx.id # assert utxo['output_index'] == 0 - mocked_store_assets.assert_called_once_with( - b.connection, - [ ( signed_create_tx.asset['data'], signed_create_tx.id, signed_create_tx.id )], - ) + if isinstance(b.connection, TarantoolDB): + mocked_store_assets.assert_called_once_with( + b.connection, # signed_create_tx.asset['data'] this was before + [(signed_create_tx.asset, signed_create_tx.id, signed_create_tx.id)], + ) + else: + mocked_store_assets.assert_called_once_with( + b.connection, # signed_create_tx.asset['data'] this was before + [(signed_create_tx.asset["data"], signed_create_tx.id, signed_create_tx.id)], + ) mocked_store_metadata.assert_called_once_with( b.connection, [{'id': signed_create_tx.id, 'metadata': signed_create_tx.metadata}], @@ -244,7 +250,7 @@ def test_store_bulk_transaction(mocker, b, signed_create_tx, mocked_store_transactions.assert_called_once_with( b.connection, [{k: v for k, v in signed_create_tx.to_dict().items() - if k not in ('asset', 'metadata')}], + if k not in ('asset', 'metadata')}], ) mocked_store_assets.reset_mock() mocked_store_metadata.reset_mock() @@ -254,7 +260,8 @@ def test_store_bulk_transaction(mocker, b, signed_create_tx, # utxo = utxoset.find_one() # assert utxo['transaction_id'] == signed_transfer_tx.id # assert utxo['output_index'] == 0 - assert not mocked_store_assets.called + if not isinstance(b.connection, TarantoolDB): + assert not mocked_store_assets.called mocked_store_metadata.asser_called_once_with( b.connection, [{'id': signed_transfer_tx.id, @@ -369,23 +376,23 @@ def test_get_spent_transaction_critical_double_spend(b, alice, bob, carol): tx = Transaction.create([alice.public_key], [([alice.public_key], 1)], - asset=asset)\ - .sign([alice.private_key]) + asset=asset) \ + .sign([alice.private_key]) tx_transfer = Transaction.transfer(tx.to_inputs(), [([bob.public_key], 1)], - asset_id=tx.id)\ - .sign([alice.private_key]) + asset_id=tx.id) \ + .sign([alice.private_key]) double_spend = Transaction.transfer(tx.to_inputs(), [([carol.public_key], 1)], - asset_id=tx.id)\ - .sign([alice.private_key]) + asset_id=tx.id) \ + .sign([alice.private_key]) same_input_double_spend = Transaction.transfer(tx.to_inputs() + tx.to_inputs(), [([bob.public_key], 1)], - asset_id=tx.id)\ - .sign([alice.private_key]) + asset_id=tx.id) \ + .sign([alice.private_key]) b.store_bulk_transactions([tx]) @@ -441,16 +448,16 @@ def test_migrate_abci_chain_yields_on_genesis(b): @pytest.mark.bdb @pytest.mark.parametrize('chain,block_height,expected', [ ( - (1, 'chain-XYZ', True), - 4, - {'height': 5, 'chain_id': 'chain-XYZ-migrated-at-height-4', - 'is_synced': False}, + (1, 'chain-XYZ', True), + 4, + {'height': 5, 'chain_id': 'chain-XYZ-migrated-at-height-4', + 'is_synced': False}, ), ( - (5, 'chain-XYZ-migrated-at-height-4', True), - 13, - {'height': 14, 'chain_id': 'chain-XYZ-migrated-at-height-13', - 'is_synced': False}, + (5, 'chain-XYZ-migrated-at-height-4', True), + 13, + {'height': 14, 'chain_id': 'chain-XYZ-migrated-at-height-13', + 'is_synced': False}, ), ]) def test_migrate_abci_chain_generates_new_chains(b, chain, block_height, @@ -475,8 +482,8 @@ def test_get_spent_key_order(b, user_pk, user_sk, user2_pk, user2_sk): tx1 = Transaction.create([user_pk], [([alice.public_key], 3), ([user_pk], 2)], - asset=None)\ - .sign([user_sk]) + asset=None) \ + .sign([user_sk]) b.store_bulk_transactions([tx1]) assert tx1.validate(b) inputs = tx1.to_inputs()