mirror of
https://github.com/planetmint/planetmint.git
synced 2025-03-30 15:08:31 +00:00
moved get_merkget_utxoset_merkle_root to dataaccessor and fixed test cases
Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com>
This commit is contained in:
parent
a06a7f986f
commit
e627eb899d
@ -364,8 +364,8 @@ def delete_unspent_outputs(connection, unspent_outputs: list):
|
||||
@register_query(TarantoolDBConnection)
|
||||
@catch_db_exception
|
||||
def get_unspent_outputs(connection, query=None): # for now we don't have implementation for 'query'.
|
||||
_utxos = connection.connect().select(TARANT_TABLE_UTXOS, []).data
|
||||
return [utx[3] for utx in _utxos]
|
||||
utxos = connection.connect().select(TARANT_TABLE_UTXOS, []).data
|
||||
return [{"transaction_id": utxo[5], "output_index": utxo[4]} for utxo in utxos]
|
||||
|
||||
|
||||
@register_query(TarantoolDBConnection)
|
||||
|
@ -1,5 +1,6 @@
|
||||
import rapidjson
|
||||
from itertools import chain
|
||||
from hashlib import sha3_256
|
||||
|
||||
from transactions import Transaction
|
||||
from transactions.common.exceptions import DoubleSpend
|
||||
@ -9,7 +10,7 @@ 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
|
||||
from planetmint.abci.utils import key_from_base64, merkleroot
|
||||
from planetmint.backend.connection import Connection
|
||||
from planetmint.backend.tarantool.const import TARANT_TABLE_TRANSACTION, TARANT_TABLE_GOVERNANCE, TARANT_TABLE_UTXOS, TARANT_TABLE_OUTPUT
|
||||
from planetmint.backend.models.block import Block
|
||||
@ -74,6 +75,7 @@ class DataAccessor:
|
||||
:obj:`list` of TransactionLink: list of ``txid`` s and ``output`` s
|
||||
pointing to another transaction's condition
|
||||
"""
|
||||
# TODO: adjust for new utxo handling, query and return outputs based on spent
|
||||
outputs = self.fastquery.get_outputs_by_public_key(owner)
|
||||
if spent is None:
|
||||
return outputs
|
||||
@ -290,6 +292,44 @@ class DataAccessor:
|
||||
for index, output in enumerate(transaction["outputs"])
|
||||
]
|
||||
|
||||
def get_utxoset_merkle_root(self):
|
||||
"""Returns the merkle root of the utxoset. This implies that
|
||||
the utxoset is first put into a merkle tree.
|
||||
|
||||
For now, the merkle tree and its root will be computed each
|
||||
time. This obviously is not efficient and a better approach
|
||||
that limits the repetition of the same computation when
|
||||
unnecesary should be sought. For instance, future optimizations
|
||||
could simply re-compute the branches of the tree that were
|
||||
affected by a change.
|
||||
|
||||
The transaction hash (id) and output index should be sufficient
|
||||
to uniquely identify a utxo, and consequently only that
|
||||
information from a utxo record is needed to compute the merkle
|
||||
root. Hence, each node of the merkle tree should contain the
|
||||
tuple (txid, output_index).
|
||||
|
||||
.. important:: The leaves of the tree will need to be sorted in
|
||||
some kind of lexicographical order.
|
||||
|
||||
Returns:
|
||||
str: Merkle root in hexadecimal form.
|
||||
"""
|
||||
utxoset = backend.query.get_unspent_outputs(self.connection)
|
||||
# TODO Once ready, use the already pre-computed utxo_hash field.
|
||||
# See common/transactions.py for details.
|
||||
|
||||
print(utxoset)
|
||||
|
||||
hashes = [
|
||||
sha3_256("{}{}".format(utxo["transaction_id"], utxo["output_index"]).encode()).digest() for utxo in utxoset
|
||||
]
|
||||
|
||||
print(sorted(hashes))
|
||||
|
||||
# TODO Notice the sorted call!
|
||||
return merkleroot(sorted(hashes))
|
||||
|
||||
@property
|
||||
def fastquery(self):
|
||||
return FastQuery(self.connection)
|
||||
|
@ -22,7 +22,6 @@ from ipld import marshal, multihash
|
||||
from uuid import uuid4
|
||||
|
||||
from planetmint.abci.rpc import MODE_COMMIT, MODE_LIST
|
||||
from tests.utils import get_utxoset_merkle_root
|
||||
|
||||
|
||||
@pytest.mark.bdb
|
||||
@ -239,19 +238,21 @@ def test_delete_many_unspent_outputs(b, alice):
|
||||
|
||||
|
||||
def test_get_utxoset_merkle_root_when_no_utxo(b):
|
||||
assert get_utxoset_merkle_root(b.models.connection) == sha3_256(b"").hexdigest()
|
||||
assert b.models.get_utxoset_merkle_root() == sha3_256(b"").hexdigest()
|
||||
|
||||
|
||||
@pytest.mark.bdb
|
||||
def test_get_utxoset_merkle_root(b, dummy_unspent_outputs):
|
||||
utxo_space = b.models.connection.get_space("utxos")
|
||||
for utxo in dummy_unspent_outputs:
|
||||
res = utxo_space.insert((uuid4().hex, utxo["transaction_id"], utxo["output_index"], utxo))
|
||||
assert res
|
||||
def test_get_utxoset_merkle_root(b, user_sk, user_pk):
|
||||
tx = Create.generate(
|
||||
[user_pk],
|
||||
[([user_pk], 8), ([user_pk], 1), ([user_pk], 4)]
|
||||
).sign([user_sk])
|
||||
|
||||
expected_merkle_root = "86d311c03115bf4d287f8449ca5828505432d69b82762d47077b1c00fe426eac"
|
||||
merkle_root = get_utxoset_merkle_root(b.models.connection)
|
||||
assert merkle_root == expected_merkle_root
|
||||
b.models.store_bulk_transactions([tx])
|
||||
|
||||
expected_merkle_root = "e5fce6fed606b72744330b28b2f6d68f2eca570c4cf8e3c418b0c3150c75bfe2"
|
||||
merkle_root = b.models.get_utxoset_merkle_root()
|
||||
assert merkle_root in expected_merkle_root
|
||||
|
||||
|
||||
@pytest.mark.bdb
|
||||
|
@ -3,7 +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
|
||||
import multiprocessing
|
||||
from hashlib import sha3_256
|
||||
|
||||
import base58
|
||||
import base64
|
||||
@ -20,7 +19,7 @@ from transactions.common.transaction_mode_types import BROADCAST_TX_COMMIT
|
||||
from transactions.types.assets.create import Create
|
||||
from transactions.types.elections.vote import Vote
|
||||
from transactions.types.elections.validator_utils import election_id_to_public_key
|
||||
from planetmint.abci.utils import merkleroot, key_to_base64
|
||||
from planetmint.abci.utils import key_to_base64
|
||||
from planetmint.abci.rpc import MODE_COMMIT, MODE_LIST
|
||||
|
||||
|
||||
@ -127,37 +126,7 @@ def generate_election(b, cls, public_key, private_key, asset_data, voter_keys):
|
||||
return election, votes
|
||||
|
||||
|
||||
def get_utxoset_merkle_root(connection):
|
||||
"""Returns the merkle root of the utxoset. This implies that
|
||||
the utxoset is first put into a merkle tree.
|
||||
|
||||
For now, the merkle tree and its root will be computed each
|
||||
time. This obviously is not efficient and a better approach
|
||||
that limits the repetition of the same computation when
|
||||
unnecesary should be sought. For instance, future optimizations
|
||||
could simply re-compute the branches of the tree that were
|
||||
affected by a change.
|
||||
|
||||
The transaction hash (id) and output index should be sufficient
|
||||
to uniquely identify a utxo, and consequently only that
|
||||
information from a utxo record is needed to compute the merkle
|
||||
root. Hence, each node of the merkle tree should contain the
|
||||
tuple (txid, output_index).
|
||||
|
||||
.. important:: The leaves of the tree will need to be sorted in
|
||||
some kind of lexicographical order.
|
||||
|
||||
Returns:
|
||||
str: Merkle root in hexadecimal form.
|
||||
"""
|
||||
utxoset = backend.query.get_unspent_outputs(connection)
|
||||
# TODO Once ready, use the already pre-computed utxo_hash field.
|
||||
# See common/transactions.py for details.
|
||||
hashes = [
|
||||
sha3_256("{}{}".format(utxo["transaction_id"], utxo["output_index"]).encode()).digest() for utxo in utxoset
|
||||
]
|
||||
# TODO Notice the sorted call!
|
||||
return merkleroot(sorted(hashes))
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user