adopted for subconditions. fixed issues with functions

This commit is contained in:
andrei 2022-03-25 15:58:58 +02:00
parent 8b8caa6ad7
commit f498415657
5 changed files with 155 additions and 50 deletions

View File

@ -30,8 +30,11 @@ class TarantoolDB:
self.drop_database()
self.init_database()
def get_connection(self, space_name: str = None):
return self.db_connect if space_name is None else self.db_connect.space(space_name)
def space(self, space_name: str):
return self.db_connect.space(space_name)
def get_connection(self):
return self.db_connect
def __read_commands(self, file_path):
with open(file_path, "r") as cmd_file:

View File

@ -11,6 +11,7 @@ from operator import itemgetter
from planetmint.backend import query
from planetmint.backend.utils import module_dispatch_registrar
from planetmint.backend.tarantool.connection import TarantoolDB
from planetmint.common.transaction import TransactionPrepare
register_query = module_dispatch_registrar(query)
@ -46,15 +47,25 @@ def _group_transaction_by_ids(connection, txids: list):
_in[4]) > 0 else None,
"fulfillment": _in[1]
} for _in in _txinputs
],
"outputs": [
]
}
if _txoutputs[0][7] is None:
_obj["outputs"] = [
{
"public_keys": [_key[3] for _key in _txkeys if _key[2] == _out[5]],
"amount": _out[1],
"condition": {"details": {"type": _out[3], "public_key": _out[4]}, "uri": _out[2]}
} for _out in _txoutputs
]
}
else:
_obj["outputs"] = [
{
"public_keys": [_key[3] for _key in _txkeys if _key[2] == _out[5]],
"amount": _out[1],
"condition": {"uri": _out[2], "details": {"subconditions": _out[7]}, "type": _out[3], "treshold": _out[6]}
} for _out in _txoutputs
]
if len(_txobject[3]) > 0:
_obj["asset"] = {
"id": _txobject[3]
@ -70,20 +81,21 @@ def _group_transaction_by_ids(connection, txids: list):
def __asset_check(object: dict, connection):
res = object.get("asset").get("id")
res = "" if res is None else res
data = object.get("asset").get("data")
_asset = object.get("asset")
data = None
_id = None
if _asset is not None:
_id = _asset.get("id")
data = _asset.get("data") if _id is None else None
if data is not None:
store_asset(connection=connection, asset=object["asset"], tx_id=object["id"], is_data=True)
elif _id is not None:
data = _id
else:
data = ""
return res
def __metadata_check(object: dict, connection):
metadata = object.get("metadata")
if metadata is not None:
space = connection.space("meta_data")
space.insert((object["id"], metadata))
return data
@register_query(TarantoolDB)
@ -92,33 +104,29 @@ def store_transactions(connection, signed_transactions: list):
inxspace = connection.space("inputs")
outxspace = connection.space("outputs")
keysxspace = connection.space("keys")
metadatasxspace = connection.space("meta_data")
assetsxspace = connection.space("assets")
for transaction in signed_transactions:
__metadata_check(object=transaction, connection=connection)
txspace.insert((transaction["id"],
transaction["operation"],
transaction["version"],
__asset_check(object=transaction, connection=connection)
))
for _in in transaction["inputs"]:
input_id = token_hex(7)
inxspace.insert((transaction["id"],
_in["fulfillment"],
_in["owners_before"],
_in["fulfills"]["transaction_id"] if _in["fulfills"] is not None else "",
str(_in["fulfills"]["output_index"]) if _in["fulfills"] is not None else "",
input_id))
for _out in transaction["outputs"]:
output_id = token_hex(7)
outxspace.insert((transaction["id"],
_out["amount"],
_out["condition"]["uri"],
_out["condition"]["details"]["type"],
_out["condition"]["details"]["public_key"],
output_id
))
for _key in _out["public_keys"]:
unique_id = token_hex(8)
keysxspace.insert((unique_id, transaction["id"], output_id, _key))
txprepare = TransactionPrepare(transaction)
txtuples = txprepare.convert_to_tuple()
txspace.insert(txtuples["transactions"])
for _in in txtuples["inputs"]:
inxspace.insert(_in)
for _out in txtuples["outputs"]:
outxspace.insert(_out)
for _key in txtuples["keys"]:
keysxspace.insert(_key)
if len(txtuples["metadata"]) > 0:
metadatasxspace.insert(txtuples["metadata"])
if txtuples["is_data"]:
assetsxspace.insert(txtuples["asset_data"])
@register_query(TarantoolDB)
@ -178,8 +186,8 @@ def store_assets(connection, assets: list):
def get_asset(connection, asset_id: str):
space = connection.space("assets")
_data = space.select(asset_id, index="assetid_search")
_data = _data.data[0]
return {"data": _data[1]}
_data = _data.data
return {"data": _data[0][1]} if len(_data) == 1 else []
@register_query(TarantoolDB)

View File

@ -20,11 +20,13 @@ import base58
from cryptoconditions import Fulfillment, ThresholdSha256, Ed25519Sha256
from cryptoconditions.exceptions import (
ParsingError, ASN1DecodeError, ASN1EncodeError, UnsupportedTypeError)
try:
from hashlib import sha3_256
except ImportError:
from sha3 import sha3_256
from secrets import token_hex
from planetmint.common.crypto import PrivateKey, hash_data
from planetmint.common.exceptions import (KeypairMismatchException,
InputDoesNotExist, DoubleSpend,
@ -34,7 +36,6 @@ from planetmint.common.exceptions import (KeypairMismatchException,
from planetmint.common.utils import serialize
from .memoize import memoize_from_dict, memoize_to_dict
UnspentOutput = namedtuple(
'UnspentOutput', (
# TODO 'utxo_hash': sha3_256(f'{txid}{output_index}'.encode())
@ -1328,3 +1329,97 @@ class Transaction(object):
raise InvalidSignature('Transaction signature is invalid.')
return True
class TransactionPrepare:
def __init__(self, _transaction):
self._transaction = _transaction
self._tuple_transaction = {
"transactions": (),
"inputs": [],
"outputs": [],
"keys": [],
"metadata": (),
"asset": "",
"asset_data": (),
"is_data": False
}
def __create_hash(self, n: int):
return token_hex(n)
def _metadata_check(self):
metadata = self._transaction.get("metadata")
self._tuple_transaction["metadata"] = (self._transaction["id"], metadata) if metadata is not None else ()
def __asset_check(self):
_asset = self._transaction.get("asset")
if _asset is None:
self._tuple_transaction["asset"] = ""
_id = _asset.get("id")
data = _asset.get("data")
if _id is not None:
self._tuple_transaction["asset"] = _id
if data is not None:
self._tuple_transaction["is_data"] = True
self._tuple_transaction["asset_data"] = (self._transaction["id"], data)
self._tuple_transaction["asset"] = self._transaction["id"]
def __prepare_inputs(self):
_inputs = []
for _input in self._transaction["inputs"]:
_inputs.append((self._transaction["id"],
_input["fulfillment"],
_input["owners_before"],
_input["fulfills"]["transaction_id"] if _input["fulfills"] is not None else "",
str(_input["fulfills"]["output_index"]) if _input["fulfills"] is not None else "",
self.__create_hash(7)))
return _inputs
def __prepare_outputs(self):
_outputs = []
_keys = []
for _output in self._transaction["outputs"]:
output_id = self.__create_hash(7)
if _output["condition"]["details"].get("subconditions") is None:
_outputs.append((self._transaction["id"],
_output["amount"],
_output["condition"]["uri"],
_output["condition"]["details"]["type"],
_output["condition"]["details"]["public_key"],
output_id,
None,
None
))
else:
_outputs.append((self._transaction["id"],
_output["amount"],
_output["condition"]["uri"],
_output["condition"]["details"]["type"],
None,
output_id,
_output["condition"]["details"]["threshold"],
_output["condition"]["details"]["subconditions"]
))
for _key in _output["public_keys"]:
key_id = self.__create_hash(7)
_keys.append((key_id, self._transaction["id"], output_id, _key))
return _keys, _outputs
def __prepare_transaction(self):
return (self._transaction["id"],
self._transaction["operation"],
self._transaction["version"],
self._tuple_transaction["asset"])
def convert_to_tuple(self):
self._metadata_check()
self.__asset_check()
self._tuple_transaction["transactions"] = self.__prepare_transaction()
self._tuple_transaction["inputs"] = self.__prepare_inputs()
keys, outputs = self.__prepare_outputs()
self._tuple_transaction["outputs"] = outputs
self._tuple_transaction["keys"] = keys
return self._tuple_transaction

View File

@ -77,7 +77,7 @@ class Planetmint(object):
else:
self.validation = BaseValidationRules
# planetmint.backend.tarantool.connection_tarantool.connect(**Config().get()['database'])
self.connection = connection if connection is not None else planetmint.backend.Connection().get_connection()
self.connection = connection if connection is not None else planetmint.backend.Connection()
def post_transaction(self, transaction, mode):
"""Submit a valid transaction to the mempool."""

View File

@ -197,7 +197,6 @@ def test_single_in_single_own_single_out_multiple_own_transfer(alice, b, user_pk
assert len(condition['condition']['details']['subconditions']) == 2
assert len(tx_transfer_signed.inputs) == 1
b.store_bulk_transactions([tx_transfer_signed])
with pytest.raises(DoubleSpend):
tx_transfer_signed.validate(b)