commit 90cd086debcfe9f5f29662f64db5ef114706f93a
parent 48aa49525fd9b0943704f7a388cad343878d97d5
Author: lash <dev@holbrook.no>
Date: Thu, 5 Feb 2026 14:07:23 +0000
WIP Strip xmlns from ledger subelements
Diffstat:
3 files changed, 72 insertions(+), 27 deletions(-)
diff --git a/dummy/tests/entry.py b/dummy/tests/entry.py
@@ -4,8 +4,9 @@ import unittest
import os
import copy
-from usawa import EntryPart, Entry, DemoWallet, ACL
+from usawa import EntryPart, Entry, DemoWallet, ACL, UnitIndex
from usawa.error import ACLError
+import lxml.etree
logging.basicConfig(level=logging.DEBUG)
logg = logging.getLogger()
@@ -19,6 +20,7 @@ class TestEntry(unittest.TestCase):
self.ref = '1bda7dfa-b8fd-400d-8b42-1d2861ad7f70'
self.description = "foo bar baz"
self.dtreg = datetime.datetime.now()
+ self.uidx = UnitIndex('FOO')
def test_entry_serialize(self):
@@ -56,6 +58,23 @@ class TestEntry(unittest.TestCase):
r = Entry.unwrap(data)
+ def test_entry_sign_verify_imported(self):
+ dst = EntryPart('FOO', 'asset', 'foo', 1337)
+ src = EntryPart('FOO', 'income', 'foo', 1337, debit=True)
+ o = Entry(42, datetime.datetime.strptime('2025-11-11', '%Y-%m-%d'), parent=self.parent, ref=self.ref, description=self.description, tx_datereg=self.dtreg)
+ o.add_part(src, debit=True)
+ o.add_part(dst)
+ wallet = DemoWallet()
+ (digest, sig, msg) = o.sign(wallet)
+ tree = o.to_tree()
+ s = lxml.etree.tostring(tree, method='c14n2')
+ logg.debug('string {}'.format(s))
+
+ tree = lxml.etree.fromstring(s)
+ o = Entry.from_tree(tree, self.uidx)
+ o.verify(wallet)
+
+
def test_entry_acl_verify(self):
dst = EntryPart('FOO', 'asset', 'foo', 1337)
src = EntryPart('FOO', 'income', 'foo', 1337, debit=True)
diff --git a/dummy/usawa/entry.py b/dummy/usawa/entry.py
@@ -73,7 +73,7 @@ class EntryPart:
if self.isdebit:
tag = 'debit'
- part = etree.Element(tag, type=self.typ)
+ part = etree.Element(tag, type=self.typ, nsmap=nsmap())
o = etree.Element('unit')
o.text = self.unit
@@ -229,18 +229,21 @@ class Entry:
description = description.text
dt = datetime.date.fromisoformat(o.find('date', namespaces=nsmap()).text)
dtreg = datetime.datetime.strptime(o.find('dateTimeRegistered', namespaces=nsmap()).text, '%Y-%m-%dT%H:%M:%SZ')
+
+ src_tree = o.find('debit', namespaces=nsmap())
+ dst_tree = o.find('credit', namespaces=nsmap())
o = Entry(serial, dt, ref=ref, parent=parent, tx_datereg=dtreg, description=description, unitindex=unitindex)
- src = EntryPart.from_tree(tree.find('src', namespaces=nsmap()), debit=True)
- dst = EntryPart.from_tree(tree.find('dst', namespaces=nsmap()))
+ src = EntryPart.from_tree(src_tree, debit=True)
+ dst = EntryPart.from_tree(dst_tree)
o.add_part(src, debit=True)
o.add_part(dst)
for sig in tree.iter(NSPREFIX + 'sig'):
- r.add_signature(sig.get('keyid'), bytes.fromhex(sig.text))
+ o.add_signature(sig.get('keyid'), bytes.fromhex(sig.text))
- return r
+ return o
"""Generate the serialization format used to calculate the digest for the entry.
@@ -401,12 +404,18 @@ class Entry:
# TODO: demo only takes into account single signature
sig = v[1][0]
entry = Entry.deserialize(v[2])
- (z, b) = entry.sum()
+ entry.add_signature(pubkey_bytes, sig)
+ entry.verify(wallet)
+ return entry
+
+
+ def verify(self, wallet):
+ (z, b) = self.sum()
+ pubkeys = list(self.sigs.keys())
+ sig = self.sigs[pubkeys[0]]
if not wallet.verify(z, sig):
raise VerifyError()
# TODO: demo only takes into account single signature
- entry.add_signature(pubkey_bytes, sig)
- return entry
"""Generate and return an XML representation of the entry.
@@ -417,7 +426,7 @@ class Entry:
"""
def to_tree(self):
#tree = etree.Element('entry', type=self.typ)
- tree = etree.Element('entry')
+ tree = etree.Element(NSPREFIX + 'entry', nsmap=nsmap())
data = etree.Element('data')
o = etree.Element('parent')
diff --git a/dummy/usawa/ledger.py b/dummy/usawa/ledger.py
@@ -213,7 +213,8 @@ class Ledger:
"""
"""
def apply_wallet(self):
- incoming = self.tree.find('incoming', namespaces=nsmap())
+ #incoming = self.tree.find('incoming', namespaces=nsmap())
+ incoming = self.tree.find('incoming')
v = self.wallet.pubkey()
try:
self.sigs[v]
@@ -268,7 +269,9 @@ class Ledger:
tree = lxml.etree.XML('<ledger xmlns="http://usawa.defalsify.org/" version="{}"></ledger>'.format(XML_FORMAT_VERSION))
if self.tree == None:
self.tree = tree
- o = lxml.etree.SubElement(tree, NSPREFIX + 'topic', nsmap=nsmap())
+ #o = lxml.etree.SubElement(tree, NSPREFIX + 'topic', nsmap=nsmap())
+ o = lxml.etree.SubElement(tree, 'topic')
+ tree.append(o)
if topic == None:
if self.topic == None:
topic = os.urandom(64)
@@ -276,11 +279,13 @@ class Ledger:
else:
topic = self.topic.hex()
o.text = topic
- o = lxml.etree.SubElement(tree, NSPREFIX + 'generated', nsmap=nsmap())
+ #o = lxml.etree.SubElement(tree, NSPREFIX + 'generated', nsmap=nsmap())
+ o = lxml.etree.SubElement(tree, 'generated')
self.dt = datetime.datetime.now()
o.text = to_datestring(self.dt)
#self.tree.append(o)
- o = lxml.etree.SubElement(tree, NSPREFIX + 'src', nsmap=nsmap())
+ #o = lxml.etree.SubElement(tree, NSPREFIX + 'src', nsmap=nsmap())
+ o = lxml.etree.SubElement(tree, 'src')
if src == None:
if self.src == None:
src = self.default_src
@@ -288,16 +293,19 @@ class Ledger:
src = self.src
o.text = src
- units = lxml.etree.SubElement(tree, NSPREFIX + 'units', nsmap=nsmap())
+ units = lxml.etree.SubElement(tree, 'units', nsmap=nsmap())
logg.debug('uidx {} units {} base {}'.format(self.uidx, units, self.uidx.base))
units.set('base', self.uidx.base)
for v in self.uidx.syms():
- unit = lxml.etree.SubElement(units, NSPREFIX + 'unit', nsmap=nsmap())
+ #unit = lxml.etree.SubElement(units, NSPREFIX + 'unit', nsmap=nsmap())
+ unit = lxml.etree.SubElement(units, 'unit')
unit.attrib['sym'] = v
- o = lxml.etree.SubElement(unit, NSPREFIX + 'precision', nsmap=nsmap())
+ #o = lxml.etree.SubElement(unit, NSPREFIX + 'precision', nsmap=nsmap())
+ o = lxml.etree.SubElement(unit, 'precision')
o.text = str(self.uidx.get(v))
#unit.append(o)
- o = lxml.etree.SubElement(unit, NSPREFIX + 'exchange', nsmap=nsmap())
+ #o = lxml.etree.SubElement(unit, NSPREFIX + 'exchange', nsmap=nsmap())
+ o = lxml.etree.SubElement(unit, 'exchange')
o.text = str(self.uidx.ex(v))
#unit.append(o)
#units.append(unit)
@@ -317,7 +325,8 @@ class Ledger:
pass
v = tree_identity.text
identities.append(keyid)
- identity = lxml.etree.SubElement(tree, NSPREFIX + 'identity', nsmap=nsmap())
+ #identity = lxml.etree.SubElement(tree, NSPREFIX + 'identity', nsmap=nsmap())
+ identity = lxml.etree.SubElement(tree, 'identity')
identity.text = v
identity.set('keyid', keyid)
identity.set('didtype', tree_identity.get('didtype'))
@@ -326,20 +335,23 @@ class Ledger:
for v in acl.pubkeys(binary=False):
if v not in identities:
identities.append(v)
- identity = lxml.etree.SubElement(tree, NSPREFIX + 'identity', nsmap=nsmap())
+ #identity = lxml.etree.SubElement(tree, NSPREFIX + 'identity', nsmap=nsmap())
+ identity = lxml.etree.SubElement(tree, 'identity')
identity.set('keyid', v)
identity.set('didtype', acl.did(v).method())
if len(identities) == 0:
logg.warning('no identities in xml, need at least one to validate against schema')
- incoming = lxml.etree.SubElement(tree, NSPREFIX + 'incoming', nsmap=nsmap())
+ #incoming = lxml.etree.SubElement(tree, NSPREFIX + 'incoming', nsmap=nsmap())
+ incoming = lxml.etree.SubElement(tree, 'incoming')
incoming.set('serial', str(self.serial))
# swap running and apply all bases
self.running = {}
- incoming_old = self.tree.find('incoming', namespaces=nsmap())
+ #incoming_old = self.tree.find('incoming', namespaces=nsmap())
+ incoming_old = self.tree.find('incoming')
logg.debug('inc {}'.format(lxml.etree.tostring(incoming_old)))
if incoming_old != None:
@@ -373,13 +385,15 @@ class Ledger:
logg.debug('add new runningtotal for {}'.format(k))
self.running[k] = RunningTotal(k, self.uidx)
- o = lxml.etree.SubElement(incoming, NSPREFIX + 'digest', nsmap=nsmap())
+ #o = lxml.etree.SubElement(incoming, NSPREFIX + 'digest', nsmap=nsmap())
+ o = lxml.etree.SubElement(incoming, 'digest')
o.attrib['algo'] = 'sha512'
o.text = self.base.hex()
if self.wallet != None:
r = self.sign()
- o = lxml.etree.SubElement(incoming, NSPREFIX + 'sig', nsmap=nsmap())
+ #o = lxml.etree.SubElement(incoming, NSPREFIX + 'sig', nsmap=nsmap())
+ o = lxml.etree.SubElement(incoming, 'sig')
o.set('keyid', self.wallet.address().hex())
o.set('type', 'ed25519')
o.text = r.hex()
@@ -541,7 +555,8 @@ class Ledger:
def apply_signature(self, identity):
sig = self.sigs[identity]
sig_hx = sig.hex()
- tree = self.tree.find('incoming', namespaces=nsmap())
+ #tree = self.tree.find('incoming', namespaces=nsmap())
+ tree = self.tree.find('incoming')
for v in tree.iter(NSPREFIX + 'sig'):
if v.get('keyid') == identity.hex():
@@ -586,7 +601,8 @@ class Ledger:
unit = units.get('base')
part = tree.find('incoming', namespaces=nsmap())
serial = int(part.get('serial'))
- o = part.find('digest', namespaces=nsmap()).text # verify that is sha512
+ #o = part.find('digest', namespaces=nsmap()).text # verify that is sha512
+ o = part.find('digest').text # verify that is sha512
r = Ledger(unitindex, topic=topic, tree=tree, acl=acl, serial=serial, base=bytes.fromhex(o))
for sig in part.iter(NSPREFIX + 'sig'):
@@ -663,7 +679,8 @@ class Ledger:
inc_tree = self.tree.find('incoming', namespaces=nsmap())
inc_tree.set('serial', str(self.base_serial))
- o = inc_tree.find('digest', namespaces=nsmap())
+ #o = inc_tree.find('digest', namespaces=nsmap())
+ o = inc_tree.find('digest')
o.text = self.base.hex()
# xpath does not support empty namespace names