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