Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • cellframe/python-cellframe-modules/pycfhelpers
1 result
Show changes
Commits on Source (3)
......@@ -13,7 +13,7 @@ from CellFrame.Chain import ChainAddr
from DAP.Core import Math
if TYPE_CHECKING:
from .net import CFNet
from .net import CFNet, CFChain
from .consensus import CFBlock, CFEvent
from CellFrame.types import ticker
......@@ -39,13 +39,13 @@ class CFDatum:
# __slots__ = ["_origin_datum", "hash", "type", "created_at", "atom", "size", "version", "net"]
def __init__(self, atom: CFBlock | CFEvent | None, datum: Datum, net: CFNet | None = None):
def __init__(self, atom: CFBlock | CFEvent | None, datum: Datum, chain: CFChain | None = None):
"""Initialize a new CFDatum instance.
Args:
atom (CFBlock | CFEvent | None): The parent atom of the datum.
datum (Datum): The datum object.
net (CFNet | None): The CFNet instance. Defaults to None.
chain (CFChain | None): The CFChain instance. Defaults to None.
Raises:
AttributeError: If atom is None and net is None.
......@@ -60,11 +60,13 @@ class CFDatum:
except OSError:
self.created_at = datetime.fromtimestamp(0)
log.error(f"Datum [{datum.hash}] has invalid timestamp!")
if atom is None and net is None:
if atom is None and chain is None:
raise AttributeError("A datum without a parent atom requires a net")
self.atom = atom # atom == None - datum in mempool
self.net = net
self.chain = chain
self.net = self.chain.net
def get_sub_datum(
self) -> CFDatumTX | CFDatumToken | CFDatumEmission | CFDatumAnchor | CFDatumDecree | CFDatumCustom:
"""Retrieve the sub-datum associated with this datum.
......@@ -105,26 +107,31 @@ class CFSubDatum:
def __init__(self, parent_datum: CFDatum | None,
sub_datum: DatumTx | DatumToken | DatumEmission | DatumDecree | DatumAnchor | bytes,
net: CFNet | None = None):
chain: CFChain | None = None):
"""Initialize a new CFSubDatum instance.
Args:
parent_datum (CFDatum | None): The parent datum associated with the sub-datum, or None if there's no parent datum.
sub_datum (Union[DatumTx, DatumToken, DatumEmission, DatumDecree, DatumAnchor, bytes]):
The sub-datum object or its bytes representation.
net (CFNet | None): The CFNet instance representing the network, defaults to None.
chain (CFChain | None): The CFChain instance representing the chain, defaults to None.
"""
self._parent_datum = parent_datum
self._origin_sub_datum = sub_datum
self.type = "DEFAULT"
self.chain = chain
if self._parent_datum and self._parent_datum.atom is None: # mempool datum
self._net = self._parent_datum.net
self.chain = self._parent_datum.chain
elif self._parent_datum: # from chains
self._net = self._parent_datum.atom.chain.net
self.chain = self._parent_datum.atom.chain
else: # some custom created emission with no parent.
self._net = net
if self.chain:
self._net = chain.net
else:
self._net = None
if sub_datum is None:
self.hash = parent_datum.hash
self.type = "CORRUPTED"
......@@ -160,17 +167,17 @@ class CFDatumTX(CFSubDatum):
CFSubDatum (CFSubDatum): a sub-datum in CellFrame
"""
def __init__(self, parent_datum: CFDatum | None, sub_datum: DatumTx, net: CFNet | None = None):
def __init__(self, parent_datum: CFDatum | None, sub_datum: DatumTx, chain: CFChain | None = None):
"""Initialize a new CFDatumTX instance.
Args:
parent_datum (CFDatum | None): The parent datum associated with the sub-datum, or None if there's no parent datum.
sub_datum (DatumTx): The transaction sub-datum object.
net (CFNet | None): The CFNet instance representing the
net (CFChain | None): The CFChain instance representing the
network context, defaults to None.
"""
super().__init__(parent_datum, sub_datum, net=net)
super().__init__(parent_datum, sub_datum, chain=chain)
if self.type == "CORRUPTED":
return
......@@ -253,7 +260,7 @@ class CFDatumEmission(CFSubDatum):
tsd (dict[str, Union[str, dict[str, Any]]]): Typed section data associated with the emission, containing various information in a structured format.
"""
def __init__(self, parent_datum: CFDatum | None, sub_datum: DatumEmission, net: CFNet | None = None):
def __init__(self, parent_datum: CFDatum | None, sub_datum: DatumEmission, chain: CFChain | None = None):
"""Initialize a new CFDatumEmission instance.
Args:
......@@ -261,14 +268,15 @@ class CFDatumEmission(CFSubDatum):
sub_datum (DatumEmission): The emission sub-datum object.
net (CFNet | None): The CFNet instance representing the network context, defaults to None.
"""
super().__init__(parent_datum, sub_datum, net=net)
from pycfhelpers.node.net import CFWalletAddress
super().__init__(parent_datum, sub_datum, chain=chain)
if self.type == "CORRUPTED":
return
self.version = sub_datum.version
self.type = sub_datum.typeStr
self.ticker: ticker = sub_datum.ticker
self.address = str(sub_datum.addr)
self.address = CFWalletAddress(str(sub_datum.addr))
self.hash = str(sub_datum.hash)
# TODO: Math --> CFMath
self.value: Math = sub_datum.value
......@@ -327,16 +335,24 @@ class CFDatumEmission(CFSubDatum):
return [sign.pkey_hash for sign in self.signs if
sign.pkey_hash in token_auth_signs_pkey_hashes]
def add_sign(self, certificate: CFCertificate | CFSign) -> CFSign:
self._origin_sub_datum.addSign(certificate._origin_certificate)
return self.signs[-1]
def add_sign(self, sign_or_cert: CFCertificate | CFSign) -> CFSign:
if isinstance(sign_or_cert, CFCertificate):
self._origin_sub_datum.addSign(sign_or_cert._origin_certificate)
return self.signs[-1]
elif isinstance(sign_or_cert, CFSign):
self._origin_sub_datum.appendSign(sign_or_cert.serialize())
return self.signs[-1]
raise TypeError(f"Sign can be addeed only by CFCertificate or by already made CFSign object")
# TODO: move to add_sign
def add_raw_sign(self, sign_data: bytes):
self._origin_sub_datum.appendSign(sign_data)
@staticmethod
def create(wallet: 'CFWalletAddress', token_symbol: str, value: int, tsd_data: dict, net: CFNet|None=None) -> CFDatumEmission:
def create(wallet: 'CFWalletAddress', token_symbol: str, value: int, tsd_data: dict, chain: CFChain|None=None) -> CFDatumEmission:
emission = DatumEmission(str(value), token_symbol, wallet._original_addr)
......@@ -348,7 +364,7 @@ class CFDatumEmission(CFSubDatum):
else:
emission.addTSD(key, str(value).encode("utf-8"))
return CFDatumEmission(parent_datum=None, sub_datum=emission, net=net)
return CFDatumEmission(parent_datum=None, sub_datum=emission, chain=chain)
class CFDatumDecree(CFSubDatum):
......
......@@ -54,6 +54,10 @@ class CFGDBCluster:
def member_delete(self, addr: CFNodeAddress, role: MemberRole):
self._cluster.memberDelete(addr)
def add_net_associate(self, net: CFNet):
self._cluster.AddNetAssociate(net.id.long)
class CFGDBGroupBase(ABC):
......
......@@ -43,7 +43,7 @@ class CFItemMapper:
"""Maps item types to corresponding CellFrame item wrapper classes."""
@staticmethod
def build(origin_item, net) -> CFItem:
def build(origin_item, chain) -> CFItem:
"""Build a CellFrame item based on the provided origin item.
Args:
......@@ -55,7 +55,7 @@ class CFItemMapper:
"""
mapping = ITEM_WRAPPER_MAPPING.get(type(origin_item))
return mapping.cf_wrapper_cls(origin_item, mapping.type, net)
return mapping.cf_wrapper_cls(origin_item, mapping.type, chain)
SubDatumMeta = namedtuple('SubDatumMapping', ['origin_method_name', 'cf_wrapper_cls'])
......
......@@ -265,7 +265,7 @@ class CFLedger:
ems = self._origin_ledger.tokenEmissionFind(HashFast.fromString(emission_hash))
if ems:
return CFDatumEmission(None, self._origin_ledger.tokenEmissionFind(HashFast.fromString(emission_hash)),
net=self.net)
chain=self.net.zerochain)
else:
return None
......@@ -275,7 +275,7 @@ class CFLedger:
tx = self._origin_ledger.txFindByHash(hf)
if tx is None:
raise ValueError(f"Not found DatumTx with hash={hash}")
return CFDatumTX(None, tx, net=self.net)
return CFDatumTX(None, tx, chain=self.net.main)
def register_ledger_tx_notification_callback(self, callback, *args, **kwargs):
def callback_wrapper(ledger, tx, *other):
......@@ -284,39 +284,76 @@ class CFLedger:
self._origin_ledger.txAddNotify(callback_wrapper, (args, kwargs))
class CFWalletAddress:
def __init__(self, address: str):
self._original_addr = ChainAddr.fromStr(address)
def net_id(self):
return CFNetID(self._original_addr.getNetId())
def __str__(self):
return str(self._original_addr)
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)
return [CFDatum(None, datum, net=self.chain.net) for datum in data.values()]
return [CFDatum(None, datum, chain=self.chain) for datum in data.values()]
def get_datum_from_bytes(self, value: bytes) -> CFDatum | None:
datum = Mempool.datumExtract(value)
if datum is None:
return None
return CFDatum(None, datum, self.chain.net)
return CFDatum(None, datum, self.chain)
def proc(self, datum_hash: str):
def proc(self, datum: CFDatum | CFSubDatum | str):
"""
Marks datum as available for acceptance
"""
Mempool.proc(datum_hash, self.chain._origin_chain)
if isinstance(datum, (CFDatum, CFSubDatum)):
proc_hash = datum.hash
elif isinstance(datum, str):
proc_hash = datum
else:
raise TypeError("mempool.proc works only with CFDatum|CFSubDatum|str as datums")
Mempool.proc(proc_hash, self.chain._origin_chain)
def put(self, datum: CFDatumEmission ) -> CFDatum:
if isinstance(datum, CFDatumEmission):
datum_hash = Mempool.emissionPlace(self.chain._origin_chain, datum._origin_sub_datum)
return CFDatum(None, Mempool.datumGet(self.chain._origin_chain, datum_hash), self.chain.net)
return CFDatum(None, Mempool.datumGet(self.chain._origin_chain, datum_hash), self.chain)
else:
raise TypeError("mempool.put works only for ems now")
def get(self, datum_hash: str | HashFast) ->CFDatum | None:
if isinstance(datum_hash, str):
hash = datum_hash
elif isinstance(datum_hash, HashFast):
hash = str(datum_hash)
else:
raise TypeError("mempool.get works only with str|HashFast objs")
datum = Mempool.datumGet(self.chain._origin_chain, hash)
print(datum)
if datum:
return CFDatum(None, datum, self.chain)
else:
return None
def create_base_transaction(self, emission: CFDatumEmission, cert: CFCertificate, fee: Math) -> HashFast:
def create_base_transaction(self, emission: CFDatumEmission, cert: CFCertificate, fee_datoshi: int) -> CFDatum | None:
emission_hash = HashFast.fromString(emission.hash)
return Mempool.baseTxCreate(
self.chain.net.main._origin_chain, emission_hash, self.chain.net.zerochain._origin_chain,
emission.value, emission.ticker, emission.address, fee, cert._origin_certificate
)
datum_hash = str(Mempool.baseTxCreate(
self.chain._origin_chain, emission_hash, emission.chain._origin_chain,
emission.value, emission.ticker, emission.address._original_addr, Math(str(fee_datoshi)), cert._origin_certificate
))
print(datum_hash)
return self.get(datum_hash)
def remove(self, datum: CFDatum | CFSubDatum | str) -> bool:
hash_to_remove = None
......@@ -326,14 +363,3 @@ class CFMempool:
hash_to_remove = datum
return Mempool.remove(self.chain._origin_chain, hash_to_remove)
class CFWalletAddress:
def __init__(self, address: str):
self._original_addr = ChainAddr.fromStr(address)
def net_id(self):
return CFNetID(self._original_addr.getNetId())
def __str__(self):
return str(self._original_addr)