usawa

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

commit 5e7ef1002ffae242360805efc33ff757aaee6f3d
parent 6d993fcd46109de4caa6d0262fe52007a4ce51de
Author: lash <dev@holbrook.no>
Date:   Tue, 17 Feb 2026 13:27:18 +0000

Use entry including sigs for lookup value

Diffstat:
Mdummy/tests/resolver.py | 39++++++++++++++++++++++-----------------
Mdummy/usawa/data/schema.xsd | 7+++++++
Mdummy/usawa/entry.py | 16++++++++++++++++
Mdummy/usawa/ledger.py | 8++++++--
Mdummy/usawa/resolve/base.py | 19+++++++++++++++++++
5 files changed, 70 insertions(+), 19 deletions(-)

diff --git a/dummy/tests/resolver.py b/dummy/tests/resolver.py @@ -63,12 +63,12 @@ class TestResolver(unittest.TestCase): ledger = Ledger(uidx, wallet=wallet, topic=bytes.fromhex(hash_of_foo)) dst = EntryPart('FOO', 'asset', 'foo', 1337) src = EntryPart('FOO', 'income', 'foo', 1337, debit=True) - entry = Entry(42, datetime.datetime.strptime('2025-11-11', '%Y-%m-%d'), parent=self.parent, tx_datereg=self.dtreg) + entry = Entry(1, datetime.datetime.strptime('2025-11-11', '%Y-%m-%d'), parent=self.parent, tx_datereg=self.dtreg) entry.add_part(src, debit=True) entry.add_part(dst) entry.sign(wallet) - ledger.add_entry(entry) first_entry_key = self.backend.put_entry(entry, 'sha512') + ledger.add_entry(entry) dst = EntryPart('FOO', 'expense', 'bar̈́', 42, debit=True) src = EntryPart('FOO', 'liability', 'bar', 42) @@ -77,23 +77,28 @@ class TestResolver(unittest.TestCase): entry.add_part(dst) entry.sign(wallet) ledger.add_entry(entry) - ledger.sign() last_entry_key = self.backend.put_entry(entry, 'sha512') + ledger.sign() - tree = ledger.to_tree(lookup='sha512') - s = lxml.etree.tostring(tree) - ledger = Ledger(uidx, wallet=wallet, topic=bytes.fromhex(hash_of_foo)) - - k = self.backend.get(first_entry_key) - first_entry = Entry.from_string(k, uidx) - ledger.add_entry(first_entry) - - k = self.backend.get(last_entry_key) - last_entry = Entry.from_string(k, uidx) - ledger.add_entry(last_entry) - - tree = ledger.to_tree(lookup='sha512') - s_orig = lxml.etree.tostring(tree) + ledger.truncate(lookup='sha512') + logg.debug('after trunc {}'.format(ledger.lookup)) + + self.backend.restore_ledger(ledger) + +# tree = ledger.to_tree(lookup='sha512') +# s = lxml.etree.tostring(tree) +# ledger = Ledger(uidx, wallet=wallet, topic=bytes.fromhex(hash_of_foo)) +# +# k = self.backend.get(first_entry_key) +# first_entry = Entry.from_string(k, uidx) +# ledger.add_entry(first_entry) +# +# k = self.backend.get(last_entry_key) +# last_entry = Entry.from_string(k, uidx) +# ledger.add_entry(last_entry) +# +# tree = ledger.to_tree(lookup='sha512') +# s_orig = lxml.etree.tostring(tree) if __name__ == '__main__': diff --git a/dummy/usawa/data/schema.xsd b/dummy/usawa/data/schema.xsd @@ -133,6 +133,13 @@ <xs:attribute name="uuid" type="xs:string" /> </xs:complexType> + <xs:complexType name="ParentRef"> + <xs:sequence> + <xs:element name="digest" type="xs:string" /> + <xs:element name="lookup" type="Lookup" minOccurs="0" maxOccurs="unbounded" /> + </xs:sequence> + </xs:complexType> + <xs:complexType name="EntryData"> <xs:sequence> <xs:element name="parent" type="xs:string" /> diff --git a/dummy/usawa/entry.py b/dummy/usawa/entry.py @@ -204,6 +204,8 @@ class Entry: self.description = description self.debit = [] self.credit = [] + self.lookup = None + self.lookup_algo = None """Add an entry part to the entry. @@ -294,6 +296,7 @@ class Entry: o = tree.find('lookup') if o != None: self.lookup_algo = o.get('algo') + self.lookup = o.text for sig in tree.iter(NSPREFIX + 'sig'): entry.add_signature(sig.get('keyid'), bytes.fromhex(sig.text)) @@ -620,6 +623,19 @@ class Entry: return (h.digest().hex(), b,) + + def tree_sum(self, lookup): + tree = self.to_tree() + b = lxml.etree.tostring(tree) + h = None + if lookup == 'sha512': + h = hashlib.sha512() + elif lookup == 'sha256': + h = hashlib.sha256() + h.update(b) + return h.digest() + + """Generate canonical XML for signature material. :return: Signature material. diff --git a/dummy/usawa/ledger.py b/dummy/usawa/ledger.py @@ -244,6 +244,7 @@ class Ledger: self.running = {} self.wallet = None self.lookup = None + self.lookup_algo = 'sha512' for k in self.uidx.syms(): if self.running.get(k) != None: @@ -466,13 +467,15 @@ class Ledger: """ def add_entry(self, entry): if self.cur != entry.parent: - raise ValueError('entry parent does not match ledger state') + raise ValueError('entry parent {} does not match ledger state {}'.format(entry.parent, self.cur)) self.check_sigs(entry) # update the internal state self.serial = entry.serial oldsum = self.cur - self.cur = entry.sum()[0] + #self.cur = entry.sum()[0] + (k, v) = entry.get_lookup(self.lookup_algo) + logg.debug('addentr entry {} {}'.format(k, v)) entry.parent = oldsum self.apply_entryparts(entry) @@ -638,6 +641,7 @@ class Ledger: return if lookup != None: (k, v) = entry.get_lookup(lookup) + logg.debug('trunc looup {} {}'.format(k, v)) self.lookup = k self.lookup_algo = lookup self.entries = {} diff --git a/dummy/usawa/resolve/base.py b/dummy/usawa/resolve/base.py @@ -3,7 +3,9 @@ import logging import hexathon +from usawa import Entry from usawa.error import VerifyError +from usawa.constant import DEFAULTPARENT logg = logging.getLogger('usawa.resolve') @@ -102,4 +104,21 @@ class BaseResolver: if lookup != None: (k, v) = entry.get_lookup(lookup) self.put(k, v.encode('utf-8')) + logg.debug('putentr entry {} {}'.format(k, v)) return k + + + def restore_ledger(self, ledger, min=0): + lookup = self.get(ledger.lookup) + while True: + entry = Entry.from_string(lookup, ledger.uidx) + if entry.serial == 0 or entry.serial < min: + break + k = entry.parent + if k == DEFAULTPARENT: + break + logg.debug('getting parent {}'.format(k.hex())) + v = self.get(k) + entry_nolookup = Entry.from_string(v, ledger.uidx) + lookup = self.get(entry_nolookup.lookup) +