Skip to content
Snippets Groups Projects
Commit 617175a7 authored by Dmitry Puzyrkov's avatar Dmitry Puzyrkov
Browse files

Merge branch 'Feature-10360' into 'main'

Feature 10360

See merge request cellframe/pycfhelpers!13
parents 7d5d2822 6bd4d64f
No related branches found
No related tags found
No related merge requests found
......@@ -19,20 +19,23 @@ from .types import ticker, TSD
class CFDatum:
__slots__ = ["_origin_datum", "hash", "type", "created_at", "atom", "size", "version"]
# __slots__ = ["_origin_datum", "hash", "type", "created_at", "atom", "size", "version", "net"]
def __init__(self, atom: CFBlock | CFEvent, datum: Datum):
def __init__(self, atom: CFBlock | CFEvent | None, datum: Datum, net: CFNet | None = None):
self._origin_datum = datum
self.size = datum.getSize()
self.hash = str(datum.hash)
self.type = datum.getTypeStr()
self.version = datum.versionStr
self.size = datum.getSize()
try:
self.created_at = datum.tsCreated
except OSError:
self.created_at = datetime.fromtimestamp(0)
logIt.error(f"Datum [{datum.hash}] has invalid timestamp!")
self.type = datum.getTypeStr()
self.hash = str(datum.hash)
self.atom = atom
if atom is None and net is None:
raise AttributeError("A datum without a parent atom requires a net")
self.atom = atom # atom == None - datum in mempool
self.net = net
def get_sub_datum(
self) -> CFDatumTX | CFDatumToken | CFDatumEmission | CFDatumAnchor | CFDatumDecree | CFDatumCustom:
......@@ -53,6 +56,8 @@ class SubDatum:
@property
def net(self) -> 'CFNet':
if self._parent_datum.atom is None: # mempool datum
return self._parent_datum.net
return self._parent_datum.atom.chain.net
......@@ -70,6 +75,10 @@ class CFDatumTX(SubDatum):
self.ticker = ledger.get_tx_ticker(self)
self.accepted = bool(ticker)
@property
def items(self) -> list[CFItem]:
return self.get_items()
def get_items(self, filter_type: type[T] | None = None) -> list[T]:
from .mappings import CFItemMapper
all_items = [CFItemMapper.build(item, self.net) for item in self._origin_sub_datum.getItems()
......@@ -132,6 +141,12 @@ class CFDatumEmission(SubDatum):
self.tsd[tsd_type.name] = tsd_data
@property
def valid_sign_hashes(self) -> list[str]:
token_auth_signs_pkey_hashes = self.net.get_ledger().token_auth_signs_pkey_hashes(self._parent_datum)
return [sign.pkey_hash for sign in self.signs if
sign.pkey_hash in token_auth_signs_pkey_hashes]
class CFDatumDecree(SubDatum):
def __init__(self, parent_datum: CFDatum, sub_datum: DatumDecree):
......
from CellFrame.Chain import GlobalDB
class GDBTable:
def __init__(self, table):
self.table = table
def set(self, key, value):
GlobalDB.set(key, self.table, value)
def get(self, key, default=None):
return GlobalDB.get(key, self.table) or default
def delete(self, key):
GlobalDB.delete(key, self.table)
def group_list(self):
return GlobalDB.grLoad(self.table)
......@@ -5,12 +5,24 @@ import traceback
from DAP.Core import logIt
from DAP.Crypto import HashFast
from CellFrame.Network import Net
from CellFrame.Chain import ChainAtomPtr, Ledger, ChainAddr
from CellFrame.Chain import ChainAtomPtr, Ledger, ChainAddr, Mempool
from .consensus import CFEvent, CFBlock
from .datums import CFDatum, CFDatumTX
from .datums import CFDatum, CFDatumTX, CFDatumEmission
from .types import CFNetState, ticker
from ..common.types import ChainTypes
from dataclasses import dataclass
class NetFee:
def __init__(self, net: 'CFNet'):
self.net = net
self.tx_fee = str(self.net._origin_net.txFee)
self.tx_fee_addr = str(self.net._origin_net.txFeeAddr)
self.validator_avg_fee = str(self.net._origin_net.validatorAverageFee)
self.validator_max_fee = str(self.net._origin_net.validatorMaxFee)
self.validator_min_fee = str(self.net._origin_net.validatorMinFee)
self.native_ticker = self.net._origin_net.nativeTicker
class CFNet:
......@@ -21,6 +33,7 @@ class CFNet:
raise RuntimeError(f"No such net: {name}")
self.main = CFChain(self, 'main')
self.zerochain = CFChain(self, 'zerochain')
self.fee_data = NetFee(self)
@property
def id(self) -> int:
......@@ -30,6 +43,22 @@ class CFNet:
def chains(self) -> list['CFChain']:
return [self.main, self.zerochain]
@property
def group_alias(self):
# net_name | group_alias
aliases = {
"mileena": "mileena",
"Backbone": "scorpion",
"KelVPN": "kelvpn",
"kelvpn-minkowski": "kelvpn-minkowski",
"raiden": "raiden",
"subzero": "subzero",
}
try:
return aliases[self.name]
except KeyError:
ValueError(f"Unknown group alias for net {self.name}")
def get_ledger(self):
return CFLedger(self, self._origin_net.getLedger())
......@@ -89,6 +118,9 @@ class CFChain:
if datum._origin_datum.isDatumTX():
yield datum.get_sub_datum()
def get_mempool(self) -> 'CFMempool':
return CFMempool(self)
def register_mempool_notification_callback(self, callback, *args, **kwargs):
def callback_wrapper(op_code, group, key, value, *other):
logIt.message(f"{other=}")
......@@ -135,8 +167,43 @@ class CFLedger:
res[ticker] = balance
return res
def token_auth_signs_pkey_hashes(self, datum: CFDatum) -> list[str]: # list[hashes]
"""
Хэши публичных ключей для подписи эмиссии тикера. cellframe-node-cli ledger list coins -net raiden
"""
pkey_hashes = self._origin_ledger.tokenAuthPkeysHashes(datum.get_sub_datum().ticker)
return [str(pkey_hash) for pkey_hash in pkey_hashes]
def token_auth_signs_valid(self, datum: CFDatum) -> int:
"""
Количество валидных подписей
"""
return self._origin_ledger.tokenAuthSignsValid(datum.get_sub_datum().ticker) or 0
def token_auth_signs_total(self, datum: CFDatum) -> int:
"""
Максимально возможное количество подписей
"""
return self._origin_ledger.tokenAuthSignsTotal(datum.get_sub_datum().ticker) or 0
def register_ledger_tx_notification_callback(self, callback, *args, **kwargs):
def callback_wrapper(ledger, tx, *other):
callback(ledger, tx, *args, net=self.net, **kwargs)
self._origin_ledger.txAddNotify(callback_wrapper, (args, kwargs))
class CFMempool:
def __init__(self, chain: CFChain):
self.chain = chain
def get_datums(self) -> list[CFDatum]:
data = Mempool.list(self.chain.net._origin_net, self.chain._origin_chain)
# logIt.message(f"{data.keys()=}")
return [CFDatum(None, datum, net=self.chain.net) for datum in data.values()]
def valid_signs_table(self):
pass
def reason(self):
pass
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment