mirror of
https://github.com/planetmint/planetmint.git
synced 2025-11-25 15:05:49 +00:00
adopted for subconditions. fixed issues with functions
This commit is contained in:
parent
8b8caa6ad7
commit
f498415657
@ -30,8 +30,11 @@ class TarantoolDB:
|
|||||||
self.drop_database()
|
self.drop_database()
|
||||||
self.init_database()
|
self.init_database()
|
||||||
|
|
||||||
def get_connection(self, space_name: str = None):
|
def space(self, space_name: str):
|
||||||
return self.db_connect if space_name is None else self.db_connect.space(space_name)
|
return self.db_connect.space(space_name)
|
||||||
|
|
||||||
|
def get_connection(self):
|
||||||
|
return self.db_connect
|
||||||
|
|
||||||
def __read_commands(self, file_path):
|
def __read_commands(self, file_path):
|
||||||
with open(file_path, "r") as cmd_file:
|
with open(file_path, "r") as cmd_file:
|
||||||
|
|||||||
@ -11,6 +11,7 @@ from operator import itemgetter
|
|||||||
from planetmint.backend import query
|
from planetmint.backend import query
|
||||||
from planetmint.backend.utils import module_dispatch_registrar
|
from planetmint.backend.utils import module_dispatch_registrar
|
||||||
from planetmint.backend.tarantool.connection import TarantoolDB
|
from planetmint.backend.tarantool.connection import TarantoolDB
|
||||||
|
from planetmint.common.transaction import TransactionPrepare
|
||||||
|
|
||||||
register_query = module_dispatch_registrar(query)
|
register_query = module_dispatch_registrar(query)
|
||||||
|
|
||||||
@ -46,15 +47,25 @@ def _group_transaction_by_ids(connection, txids: list):
|
|||||||
_in[4]) > 0 else None,
|
_in[4]) > 0 else None,
|
||||||
"fulfillment": _in[1]
|
"fulfillment": _in[1]
|
||||||
} for _in in _txinputs
|
} 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]],
|
"public_keys": [_key[3] for _key in _txkeys if _key[2] == _out[5]],
|
||||||
"amount": _out[1],
|
"amount": _out[1],
|
||||||
"condition": {"details": {"type": _out[3], "public_key": _out[4]}, "uri": _out[2]}
|
"condition": {"details": {"type": _out[3], "public_key": _out[4]}, "uri": _out[2]}
|
||||||
} for _out in _txoutputs
|
} 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:
|
if len(_txobject[3]) > 0:
|
||||||
_obj["asset"] = {
|
_obj["asset"] = {
|
||||||
"id": _txobject[3]
|
"id": _txobject[3]
|
||||||
@ -70,20 +81,21 @@ def _group_transaction_by_ids(connection, txids: list):
|
|||||||
|
|
||||||
|
|
||||||
def __asset_check(object: dict, connection):
|
def __asset_check(object: dict, connection):
|
||||||
res = object.get("asset").get("id")
|
_asset = object.get("asset")
|
||||||
res = "" if res is None else res
|
data = None
|
||||||
data = object.get("asset").get("data")
|
_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:
|
if data is not None:
|
||||||
store_asset(connection=connection, asset=object["asset"], tx_id=object["id"], is_data=True)
|
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
|
return data
|
||||||
|
|
||||||
|
|
||||||
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))
|
|
||||||
|
|
||||||
|
|
||||||
@register_query(TarantoolDB)
|
@register_query(TarantoolDB)
|
||||||
@ -92,33 +104,29 @@ def store_transactions(connection, signed_transactions: list):
|
|||||||
inxspace = connection.space("inputs")
|
inxspace = connection.space("inputs")
|
||||||
outxspace = connection.space("outputs")
|
outxspace = connection.space("outputs")
|
||||||
keysxspace = connection.space("keys")
|
keysxspace = connection.space("keys")
|
||||||
|
metadatasxspace = connection.space("meta_data")
|
||||||
|
assetsxspace = connection.space("assets")
|
||||||
|
|
||||||
for transaction in signed_transactions:
|
for transaction in signed_transactions:
|
||||||
__metadata_check(object=transaction, connection=connection)
|
txprepare = TransactionPrepare(transaction)
|
||||||
txspace.insert((transaction["id"],
|
txtuples = txprepare.convert_to_tuple()
|
||||||
transaction["operation"],
|
|
||||||
transaction["version"],
|
txspace.insert(txtuples["transactions"])
|
||||||
__asset_check(object=transaction, connection=connection)
|
|
||||||
))
|
for _in in txtuples["inputs"]:
|
||||||
for _in in transaction["inputs"]:
|
inxspace.insert(_in)
|
||||||
input_id = token_hex(7)
|
|
||||||
inxspace.insert((transaction["id"],
|
for _out in txtuples["outputs"]:
|
||||||
_in["fulfillment"],
|
outxspace.insert(_out)
|
||||||
_in["owners_before"],
|
|
||||||
_in["fulfills"]["transaction_id"] if _in["fulfills"] is not None else "",
|
for _key in txtuples["keys"]:
|
||||||
str(_in["fulfills"]["output_index"]) if _in["fulfills"] is not None else "",
|
keysxspace.insert(_key)
|
||||||
input_id))
|
|
||||||
for _out in transaction["outputs"]:
|
if len(txtuples["metadata"]) > 0:
|
||||||
output_id = token_hex(7)
|
metadatasxspace.insert(txtuples["metadata"])
|
||||||
outxspace.insert((transaction["id"],
|
|
||||||
_out["amount"],
|
if txtuples["is_data"]:
|
||||||
_out["condition"]["uri"],
|
assetsxspace.insert(txtuples["asset_data"])
|
||||||
_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))
|
|
||||||
|
|
||||||
|
|
||||||
@register_query(TarantoolDB)
|
@register_query(TarantoolDB)
|
||||||
@ -178,8 +186,8 @@ def store_assets(connection, assets: list):
|
|||||||
def get_asset(connection, asset_id: str):
|
def get_asset(connection, asset_id: str):
|
||||||
space = connection.space("assets")
|
space = connection.space("assets")
|
||||||
_data = space.select(asset_id, index="assetid_search")
|
_data = space.select(asset_id, index="assetid_search")
|
||||||
_data = _data.data[0]
|
_data = _data.data
|
||||||
return {"data": _data[1]}
|
return {"data": _data[0][1]} if len(_data) == 1 else []
|
||||||
|
|
||||||
|
|
||||||
@register_query(TarantoolDB)
|
@register_query(TarantoolDB)
|
||||||
|
|||||||
@ -20,11 +20,13 @@ import base58
|
|||||||
from cryptoconditions import Fulfillment, ThresholdSha256, Ed25519Sha256
|
from cryptoconditions import Fulfillment, ThresholdSha256, Ed25519Sha256
|
||||||
from cryptoconditions.exceptions import (
|
from cryptoconditions.exceptions import (
|
||||||
ParsingError, ASN1DecodeError, ASN1EncodeError, UnsupportedTypeError)
|
ParsingError, ASN1DecodeError, ASN1EncodeError, UnsupportedTypeError)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from hashlib import sha3_256
|
from hashlib import sha3_256
|
||||||
except ImportError:
|
except ImportError:
|
||||||
from sha3 import sha3_256
|
from sha3 import sha3_256
|
||||||
|
|
||||||
|
from secrets import token_hex
|
||||||
from planetmint.common.crypto import PrivateKey, hash_data
|
from planetmint.common.crypto import PrivateKey, hash_data
|
||||||
from planetmint.common.exceptions import (KeypairMismatchException,
|
from planetmint.common.exceptions import (KeypairMismatchException,
|
||||||
InputDoesNotExist, DoubleSpend,
|
InputDoesNotExist, DoubleSpend,
|
||||||
@ -34,7 +36,6 @@ from planetmint.common.exceptions import (KeypairMismatchException,
|
|||||||
from planetmint.common.utils import serialize
|
from planetmint.common.utils import serialize
|
||||||
from .memoize import memoize_from_dict, memoize_to_dict
|
from .memoize import memoize_from_dict, memoize_to_dict
|
||||||
|
|
||||||
|
|
||||||
UnspentOutput = namedtuple(
|
UnspentOutput = namedtuple(
|
||||||
'UnspentOutput', (
|
'UnspentOutput', (
|
||||||
# TODO 'utxo_hash': sha3_256(f'{txid}{output_index}'.encode())
|
# TODO 'utxo_hash': sha3_256(f'{txid}{output_index}'.encode())
|
||||||
@ -1328,3 +1329,97 @@ class Transaction(object):
|
|||||||
raise InvalidSignature('Transaction signature is invalid.')
|
raise InvalidSignature('Transaction signature is invalid.')
|
||||||
|
|
||||||
return True
|
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
|
||||||
|
|||||||
@ -77,7 +77,7 @@ class Planetmint(object):
|
|||||||
else:
|
else:
|
||||||
self.validation = BaseValidationRules
|
self.validation = BaseValidationRules
|
||||||
# planetmint.backend.tarantool.connection_tarantool.connect(**Config().get()['database'])
|
# 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):
|
def post_transaction(self, transaction, mode):
|
||||||
"""Submit a valid transaction to the mempool."""
|
"""Submit a valid transaction to the mempool."""
|
||||||
|
|||||||
@ -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(condition['condition']['details']['subconditions']) == 2
|
||||||
|
|
||||||
assert len(tx_transfer_signed.inputs) == 1
|
assert len(tx_transfer_signed.inputs) == 1
|
||||||
|
|
||||||
b.store_bulk_transactions([tx_transfer_signed])
|
b.store_bulk_transactions([tx_transfer_signed])
|
||||||
with pytest.raises(DoubleSpend):
|
with pytest.raises(DoubleSpend):
|
||||||
tx_transfer_signed.validate(b)
|
tx_transfer_signed.validate(b)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user