usawa

Unnamed repository; edit this file 'description' to name the repository.
Info | Log | Files | Refs | Submodules | LICENSE

commit 4ccf853837029c63bbe712d24fc83132ad9dd6fd
parent d0749b09d4d3ea464d87ece2f694bcc2f6af1026
Author: lash <dev@holbrook.no>
Date:   Mon,  9 Feb 2026 18:48:15 +0000

Update docs for store

Diffstat:
Mdummy/usawa/entry.py | 40+++++++++++++++++++++++++++-------------
Mdummy/usawa/ledger.py | 5+++++
Mdummy/usawa/store.py | 58++++++++++++++++++++++++++++++++++++++++++++++++++--------
Mdummy/usawa/xml.py | 15++++++---------
4 files changed, 88 insertions(+), 30 deletions(-)

diff --git a/dummy/usawa/entry.py b/dummy/usawa/entry.py @@ -108,7 +108,7 @@ class EntryPart: class Entry: - digest_algo = 'sha512' # The algorithm used for generating entry digests. Must match a hashlib (standard library) type. + digest_algo = 'sha512' # The algorithm used for generating entry digests. Must match a hashlib (standard library) type string identifier. """Entry represents a single pair of accounts, credit and debit, for a transaction. @@ -129,11 +129,12 @@ class Entry: :param tx_datereg: Date and time entry was added to the ledger. If not set, the current date and time will be used. :type tx_datereg: datetime.datetime :param unitindex: Unix index top validate unit symbols and exchange rates against. - :type unit: UnitIndex + :type unitindex: UnitIndex :todo: Add an optional time part to the entry, e.g. for POS items. :todo: Implement throw error if non-zero serial has zero-value digest. :todo: Check hashlen of parent against actual digest length defined in digest_algo. :todo: Prevent changes after the first signature calculation. + :todo: Ensure canonical format of keyid. """ def __init__(self, serial, tx_date, ref=None, description=None, parent=None, tx_datereg=None, unitindex=None): if isinstance(parent, str): @@ -187,7 +188,7 @@ class Entry: :param digest: The digest of the asset. :type digest: bytes :param description: Optional description string for the asset. - :type digest: str + :type description: str :param slug: Optional machine-friendly name, e.g. used as filename stem. :type slug: str """ @@ -200,7 +201,7 @@ class Entry: :param keyid: Key identifier, e.g. as used in a DID. :type keyid: str or bytes :param sigdata: Key identifier, e.g. as used in a DID. - :type keyid: bytes + :type sigdata: bytes """ def add_signature(self, keyid, sigdata): if isinstance(keyid, bytes): @@ -252,14 +253,12 @@ class Entry: return o + """Generate the simple data structure used for rencode serialization. - """Generate the serialization format used to calculate the digest for the entry. - - :returns: String representation of the entry, in rencode format. - :rtype: str + :returns: data structure + :rtype: list """ - def serialize(self): - + def to_list(self): debit = [] credit = [] for v in self.debit: @@ -278,7 +277,18 @@ class Entry: debit, credit, ] - return rencode.dumps(d) + return d + + + """Generate the serialization format used to calculate the digest for the entry. + + :returns: String representation of the entry, in rencode format. + :rtype: str + """ + def serialize(self): + b = self.to_list() + return rencode.dumps(b) + """Create an entry object from serialized data. @@ -393,11 +403,11 @@ class Entry: :raises: usawa.VerifyError if entry data could not be verified with any available public key. :returns: The entry object. :rtype: usawa.Entry + :todo: Current version only takes into account single signature """ @staticmethod def unwrap(data, acl=None): v = rencode.loads(data) - # TODO: demo only takes into account single signature pubkey_bytes = v[0][0][1] if acl != None: label = None @@ -408,7 +418,6 @@ class Entry: if not acl.may(label, 0x01): raise ACLError() wallet = DemoWallet(publickey=pubkey_bytes) - # TODO: demo only takes into account single signature sig = v[1][0] entry = Entry.deserialize(v[2]) entry.add_signature(pubkey_bytes, sig) @@ -482,6 +491,11 @@ class Entry: return tree + """Generate canonical XML for signature material. + + :return: Signature material. + :rtype: str + """ def canon(self): tree = self.to_tree() b = lxml.etree.canonicalize(tree, strip_text=True, exclude_tags=['sig']) diff --git a/dummy/usawa/ledger.py b/dummy/usawa/ledger.py @@ -633,6 +633,11 @@ class Ledger: return self.cur + """Generate canonical XML for signature material. + + :return: Signature material. + :rtype: str + """ def canon(self): tree = self.to_tree() b = lxml.etree.canonicalize(tree, strip_text=True, exclude_tags=['sig']) diff --git a/dummy/usawa/store.py b/dummy/usawa/store.py @@ -16,6 +16,15 @@ PFX_ENTRY = b'\x04' logg = logging.getLogger('usawa.store') +"""DB key prefix for a private key entry + +If public key is not specified, the prefix will reference the DEFAULT key. + +:param pubkey: Public key to get private key for. +:type pubkey: bytes +:return: DB prefix +:rtype: bytes +""" def pfx_key(pubkey=None): v = PFX_KEY if pubkey == None: @@ -23,6 +32,13 @@ def pfx_key(pubkey=None): return v + pubkey +"""DB key prefix for the ledger state of a topic. + +:param topic: Legder topic. +:type topic: bytes +:return: DB prefix +:rtype: bytes +""" def pfx_ledger_topic(topic): """Return ledger store prefix for topic. @@ -34,6 +50,14 @@ def pfx_ledger_topic(topic): r = PFX_LEDGER + topic return r + +"""DB key prefix for locking the ledger state of a topic. + +:param topic: Legder topic. +:type topic: bytes +:return: DB prefix +:rtype: bytes +""" def pfx_ledger_lock(topic): """Return ledger store locking prefix for topic. @@ -46,12 +70,15 @@ def pfx_ledger_lock(topic): return r -#def pfx_ledger(ledger): -# if not isinstance(ledger, Ledger): -# raise ValueError('invalid ledger') -# return pfx_ledger_topic(topic) - +"""DB key prefix for adding an entry to a ledger. +:param ledger: Ledger object. +:type ledger: usawa.Ledger +:param entry: Entry object to add to ledger. +:type entry: usawa.Entry +:return: DB prefix +:rtype: bytes +""" def pfx_entry(ledger, entry): """Return ledger store prefix for an entry. @@ -91,6 +118,8 @@ class LedgerStore(Interface): self.__o = implementation + """Implements whee.Interface.start + """ def start(self): serial = 0 k = pfx_ledger_topic(self.ledger.topic) @@ -103,6 +132,8 @@ class LedgerStore(Interface): self.ledger.serial = serial + """Implements whee.Interface.lock + """ def lock(self): k = pfx_ledger_lock(self.ledger.topic) v = None @@ -115,6 +146,8 @@ class LedgerStore(Interface): # atomic until here + """Implements whee.Interface.unlock + """ def unlock(self): k = pfx_ledger_lock(self.ledger.topic) v = self.__o.delete(k) @@ -124,6 +157,8 @@ class LedgerStore(Interface): :param entry: Entry to add. :type entry: usawa.Entry or int + :param update_ledger: Add the underlying ledger object with the entry. + :type update_ledger: boolean :raises: ValueError if the entry is not the right object type. :raises: FileExistsError if entry is already in store. """ @@ -140,7 +175,7 @@ class LedgerStore(Interface): :param entry: Entry of entry serial to restore. :type entry: usawa.Entry or int - :param acl: Optional list of public keys to validate signatures against. + :param acl: Optional collection of public keys to validate signatures against. :type acl: usawa.ACL :raises: PermissionError if the entry does not have a valid signature. :raises: ValueError if the serial number cannot be retrieved from the entry argument. @@ -161,7 +196,6 @@ class LedgerStore(Interface): :raises FileNotFoundError: If an entry cannot be found. """ def load(self): - #self.ledger.reset() logg.debug('load ledger from store {}'.format(self.ledger)) while True: o = None @@ -169,7 +203,6 @@ class LedgerStore(Interface): o = self.get_entry(self.ledger.next_serial()) except FileNotFoundError: break - #self.ledger.add_entry(o, modify_tree=True) self.ledger.add_entry(o) @@ -196,6 +229,15 @@ class LedgerStore(Interface): self.__o.put(k, wallet.privkey()) + """Get corresponding private key from the store. + + If public key is not supplied, will retrieve the default private key. + + :param pubkey: Public key to retrieve private key for. + :type pubkey: bytes + :return: Resulting key + :rtype: bytes + """ def get_key(self, pubkey=None): if pubkey == None: k = pfx_key() diff --git a/dummy/usawa/xml.py b/dummy/usawa/xml.py @@ -9,20 +9,17 @@ XML_FORMAT_VERSION = 1 script_dir = os.path.realpath(os.path.dirname(__file__)) - +"""Namespaces to use in ledger XML tree operations. +""" def nsmap(): - """Namespaces to use in ledger XML tree operations. - """ return NAMESPACES - +"""Parse ledger XML tree from XML string. +""" def parse(v): - """Parse ledger XML tree from XML string. - """ return lxml.etree.fromstring(v) - +"""Generate XML string from ledger XML tree. +""" def dump(v): - """Generate XML string from ledger XML tree. - """ return lxml.etree.tostring(v)