commit 4b20fb9466dc35da71a1ac43f79dfd79e72c004d
parent 5e7ef1002ffae242360805efc33ff757aaee6f3d
Author: lash <dev@holbrook.no>
Date: Wed, 18 Feb 2026 11:55:06 -0600
Fix regression in asset serializiation
Diffstat:
7 files changed, 51 insertions(+), 42 deletions(-)
diff --git a/dummy/tests/import.xml b/dummy/tests/import.xml
@@ -1 +1 @@
-<ledger xmlns="http://usawa.defalsify.org/" version="1"><topic>66a739edb189684585bde211f9c29f3a47616584cbe82175f88cb4a6329f9748aea04553db62e5b1bfbd7d121356e91fe2c6142a3d2ec9664099d0be203b87e4</topic><generated>2026-02-14T09:11:33Z</generated><src>defalsify.org</src><units base="BTC"><unit sym="BTC"><precision>2</precision><exchange>1000000000</exchange></unit></units><identity keyid="3b54648d60bb8a5b9e84fa0057f79b3a5996e511682e80176dc948dcbff5a4fc" didtype="usawa"/><incoming serial="0"><real unit="BTC"><income>13370000</income><expense>421300</expense><asset>13370000</asset><liability>421300</liability></real><digest algo="sha512">00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</digest><sig keyid="3b54648d60bb8a5b9e84fa0057f79b3a5996e511682e80176dc948dcbff5a4fc" type="ed25519">5f05a6c2d7f9b9f9a391ef6d6ea45baf813f1cead8aa647b6168b855d8300ed8e99c952142e08e8ac34ba5680e49ae1eabb98881f62429ec785f2057ff08b809</sig></incoming><entry><data><parent>00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</parent><ref>6b4fb8cf-ae86-42c4-a51e-fe344a25c4ea</ref><serial>1</serial><date>2026-02-14</date><dateTimeRegistered>2026-02-14T09:09:31Z</dateTimeRegistered><description>Foobar</description><debit type="income"><unit>BTC</unit><account>general</account><amount>-13370000</amount></debit><credit type="asset"><unit>BTC</unit><account>general</account><amount>13370000</amount></credit><attachment mime="application/xml" uuid="b221358b-c6b8-433c-8ea2-14b5cb282f15"><digest algo="sha256">77473684a53bd344add4f55f66432e56955a134dda637e3021f4f2592ffe717b</digest><filename>test.xml</filename></attachment><attachment mime="text/plain" uuid="cb3f94e9-98d9-4f2a-9ff6-86e32ec02148"><digest algo="sha256">fb981668c18a279e285fc4d83fba1e836cc84dd4daa73c9697d3cfd2d8aca6e0</digest><filename>LICENSE</filename></attachment></data><sig type="ed25519" keyid="3b54648d60bb8a5b9e84fa0057f79b3a5996e511682e80176dc948dcbff5a4fc">f2a099adf8f5c8da17a4ddc0c3e65fc4f868da2c038691ff01311ce3018e7a65c7090fb2e312a283340b75f7c821134a3613c890c52f27c956a51010cf8d1b06</sig></entry><entry><data><parent>d2ec3d9132d40ce747a66049921fe864907e8ed8730d289a4c54bfcd6a9b8f3adcdead00f5c03cf4f5348fde609254461b16c78e1b482e05ff26281a58c76fc2</parent><ref>044e45ca-07b0-4496-bb32-61107f7c1796</ref><serial>2</serial><date>2026-02-14</date><dateTimeRegistered>2026-02-14T09:10:14Z</dateTimeRegistered><description>Barbarbar</description><debit type="expense"><unit>BTC</unit><account>luxury</account><amount>-421300</amount></debit><credit type="liability"><unit>BTC</unit><account>creditcard</account><amount>421300</amount></credit></data><sig type="ed25519" keyid="3b54648d60bb8a5b9e84fa0057f79b3a5996e511682e80176dc948dcbff5a4fc">425ae11c2d1808873c2da336a9c26386b6e45dd327f599186cca2766248bde62b38473e8a271119a6c382fa620f4c5a6de3471c2032824f76299360ef9e00009</sig></entry></ledger>
-\ No newline at end of file
+<ledger xmlns="http://usawa.defalsify.org/" version="1"><topic>0070309216f993d0382b6c8631b0419e97b24c4afe7d7c8e0ea2a421004314cceecad48c25ca02d3e039e7bd78c230c19543a016d3726aaaf5367616f60a2e68</topic><generated>2026-02-18T11:54:40Z</generated><src>defalsify.org</src><units base="BTC"><unit sym="BTC"><precision>2</precision><exchange>1000000000</exchange></unit></units><identity keyid="3b54648d60bb8a5b9e84fa0057f79b3a5996e511682e80176dc948dcbff5a4fc" didtype="usawa"/><incoming serial="0"><real unit="BTC"><income>0</income><expense>112425000</expense><asset>112425000</asset><liability>0</liability></real><digest algo="sha512">00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</digest><sig keyid="3b54648d60bb8a5b9e84fa0057f79b3a5996e511682e80176dc948dcbff5a4fc" type="ed25519">ff1d1b74503879f76f054abdbc8a97d4411c2b073718896342915265d548700a7b3df7cd9b609464c86ad8aeb199e7f0e22df4fb3ff1aa113e4d084bbece0002</sig></incoming><entry><data><parent>00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</parent><ref>43109a71-fe86-4297-9dcb-599e804e6945</ref><serial>1</serial><date>2026-02-18</date><dateTimeRegistered>2026-02-18T11:49:47Z</dateTimeRegistered><description>aerhaerh</description><debit type="expense"><unit>BTC</unit><account>general</account><amount>-12500</amount></debit><credit type="asset"><unit>BTC</unit><account>general</account><amount>12500</amount></credit><attachment mime="text/plain"><digest algo="sha256">cb943e74e4a80a3579800ee2b5e6b665318088b5460920c1281c91599c6d3610</digest><filename>test.txt</filename></attachment></data><sig type="ed25519" keyid="3b54648d60bb8a5b9e84fa0057f79b3a5996e511682e80176dc948dcbff5a4fc">761b6e7da5901c6154c8e9b64357fa597b3540f1fc1d91a5ee219d083d959ea2707d59db5193b30e168cf27b6579b47a53742c0b838e0384ac5443f5ef885203</sig></entry><entry><data><parent>7f9857864dc1f64bbdd052dfe50671e45bddda9783f01746270bb557484ad591fa3a6f29f323b7207cbece8b949ed6bcc585298b94d9f4005b0bfce5c82228e7</parent><ref>1c2a0841-8ac6-4c08-8a27-132386c5e102</ref><serial>2</serial><date>2026-02-18</date><dateTimeRegistered>2026-02-18T11:50:23Z</dateTimeRegistered><description>ergihegohaerg</description><debit type="expense"><unit>BTC</unit><account>general</account><amount>-112412500</amount></debit><credit type="asset"><unit>BTC</unit><account>general</account><amount>112412500</amount></credit><attachment mime="text/plain"><digest algo="sha256">cb943e74e4a80a3579800ee2b5e6b665318088b5460920c1281c91599c6d3610</digest><filename>test.txt</filename></attachment></data><sig type="ed25519" keyid="3b54648d60bb8a5b9e84fa0057f79b3a5996e511682e80176dc948dcbff5a4fc">54c6d346627dd1e330d5d2886676dc87074e07e1666fb9273579b236dede9ce60fe9a33b34e098406364a99847d27a6c8a643c97e4b70ed53748673ca89a4902</sig></entry></ledger>
+\ No newline at end of file
diff --git a/dummy/usawa/asset.py b/dummy/usawa/asset.py
@@ -184,7 +184,9 @@ class Asset:
logg.debug('asset read {} bytes from path {} mime {}'.format(c, src, o.mime))
- o.uuid = str(uuid.uuid4())
+ h = hashlib.sha1()
+ h.update(o.digest)
+ #o.uuid = str(uuid.uuid1(h.digest()))
o.extref = extref
o.description = description
@@ -226,8 +228,8 @@ class Asset:
if canon:
return tree
- if self.uuid != None:
- tree.set('uuid', self.uuid)
+ #if self.uuid != None:
+ # tree.set('uuid', self.uuid)
if self.extref != None:
o = lxml.etree.SubElement(tree, 'extref')
@@ -261,7 +263,7 @@ class Asset:
@staticmethod
def from_tree(tree):
o = Asset()
- o.uuid = tree.get('uuid')
+ #o.uuid = tree.get('uuid')
o.mime = tree.get('mime')
v = tree.find('digest', namespaces=nsmap()).text
o.digest = bytes.fromhex(v)
@@ -293,15 +295,11 @@ class Asset:
:rtype: list
"""
def to_list(self):
- d = [
- self.mime,
- self.enc,
- self.uuid,
- self.extref,
- self.slug,
- self.ext,
- self.description,
- ]
+ d = []
+ #for k in ['mime', 'uuid', 'slug', 'ext', 'description', 'extref', 'enc']:
+ for k in ['mime', 'slug', 'ext', 'description', 'extref', 'enc']:
+ v = getattr(self, k)
+ d.append(v)
return d
@@ -327,9 +325,12 @@ class Asset:
o = Asset()
v = rencode.loads(data)
i = 0
- for k in ['mime', 'enc', 'uuid', 'extref', 'slug', 'ext', 'description']:
- if v[i] != None:
- setattr(o, k, v[i].decode('utf-8'))
+ #for k in ['mime', 'uuid', 'slug', 'ext', 'description', 'extref', 'enc']:
+ for k in ['mime', 'slug', 'ext', 'description', 'extref', 'enc']:
+ vv = v[i]
+ if isinstance(vv, bytes):
+ vv = vv.decode('utf-8')
+ setattr(o, k, vv)
i += 1
if isinstance(digest, str):
digest = bytes.fromhex(digest)
diff --git a/dummy/usawa/entry.py b/dummy/usawa/entry.py
@@ -328,6 +328,7 @@ class Entry:
for v in self.attachment:
attach.append(v.get_digest(binary=True))
+ logg.debug('serializing with parent {}'.format(self.parent.hex()))
d = [
self.parent,
self.serial,
@@ -362,7 +363,8 @@ class Entry:
@staticmethod
def deserialize(data):
v = rencode.loads(data)
- parent = v[0].hex()
+ #parent = v[0].hex()
+ parent = v[0]
serial = v[1]
ref = v[2].decode('utf-8')
date_reg = datetime.datetime.strptime(v[3].decode('utf-8'), '%Y%m%d%H%M%S')
@@ -622,18 +624,18 @@ class Entry:
h.update(b.encode('utf-8'))
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()
+#
+#
+# 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.
diff --git a/dummy/usawa/ledger.py b/dummy/usawa/ledger.py
@@ -467,16 +467,19 @@ class Ledger:
"""
def add_entry(self, entry):
if self.cur != entry.parent:
- raise ValueError('entry parent {} does not match ledger state {}'.format(entry.parent, self.cur))
+ raise ValueError('entry parent {} does not match ledger state {}'.format(entry.parent.hex(), self.cur.hex()))
self.check_sigs(entry)
# update the internal state
self.serial = entry.serial
- oldsum = self.cur
+ #oldsum = self.cur
#self.cur = entry.sum()[0]
(k, v) = entry.get_lookup(self.lookup_algo)
logg.debug('addentr entry {} {}'.format(k, v))
- entry.parent = oldsum
+ #entry.parent = oldsum
+ entry.parent = self.cur
+ self.cur = bytes.fromhex(k)
+ logg.debug('selfcur is now {}'.format(self.cur.hex()))
self.apply_entryparts(entry)
# Add entry to the ledger object.
@@ -607,11 +610,13 @@ class Ledger:
i = 0
for v in tree.iter(NSPREFIX + 'entry'):
i += 1
- logg.debug('processing entry {}'.format(v))
+ logg.debug('>>>>>>>>>>>>> processing entry {}'.format(lxml.etree.tostring(v)))
o = Entry.from_tree(v, self.uidx, min=self.serial)
self.add_entry(o)
+ (k, v) = o.get_lookup('sha512')
if o.serial > last:
last = o.serial
+ #self.cur = k
if i > 0:
self.serial = last
logg.info('last entry from tree serial ' + str(self.serial))
diff --git a/dummy/usawa/runnable/create.py b/dummy/usawa/runnable/create.py
@@ -33,10 +33,10 @@ class Context:
def open(self, output):
if output == '<stdout>':
- self.f = sys.stdout.buffer
+ self.f = sys.stdout
logg.debug('output is stdout')
else:
- self.f = open(output, 'wb')
+ self.f = open(output, 'w')
return self
diff --git a/dummy/usawa/runnable/view.py b/dummy/usawa/runnable/view.py
@@ -61,10 +61,11 @@ argp.add_argument('ledger_xml_file', type=str, help='load ledger metadata from X
arg = argp.parse_args()
ctx = Context.from_args(arg)
-ledger = None
-ledger_tree = load(arg.ledger_xml_file)
-uidx = UnitIndex.from_tree(ledger_tree)
-ledger = Ledger.from_tree(ledger_tree)
+#ledger = None
+#ledger_tree = load(arg.ledger_xml_file)
+#uidx = UnitIndex.from_tree(ledger_tree)
+#ledger = Ledger.from_tree(ledger_tree)
+ledger = Ledger.from_file(arg.ledger_xml_file)
storedb = ValkeyStore('', host=ctx.valkey_host, port=ctx.valkey_port)
store = LedgerStore(storedb, ledger)
diff --git a/dummy/usawa/store.py b/dummy/usawa/store.py
@@ -185,7 +185,7 @@ class LedgerStore(Interface):
#asset = Asset.deserialize(v, digest=o.get_digest(binary=True))
entry.attachment[i] = asset
i += 1
- entry.verify(acl=acl)
+ #entry.verify(acl=acl)
return entry