commit 90b84aa7e785b839d67b1976c990eac29db7fc90
parent aa006873c4b84f9ed0ef8646e9787e1d9cfaa3c6
Author: lash <dev@holbrook.no>
Date: Thu, 6 Nov 2025 01:41:51 +0000
WIP add signature verifier
Diffstat:
4 files changed, 81 insertions(+), 13 deletions(-)
diff --git a/README b/README
@@ -1,7 +1,8 @@
Example in folder dummy.
-It includes two demo data files:
+It includes three demo data files:
+* empty.xml
* running.xml
* present.xsl
@@ -15,7 +16,7 @@ It is still missing a schema, that's next step.
present.xsl is a small stylesheet stub just to demonstrate how xsl transformations work.
---
+---
To run the python example:
@@ -34,9 +35,18 @@ pip install -r requirements.txt
# demo.py just loads the state of the xml and outputs a bit of the data loaded
python demo.py
-# create.py adds an entry to the ledger with signature and outputs the updated xml
-python create.py 124
-
# The makefile has a single stanza that performs xsl transformation on the xml
make
```
+
+
+The `create.py` script can add entries starting with the empty.xml:
+
+```
+# create.py adds an entry to the ledger with signature and outputs the updated xml
+python create.py --xml-file empty.xml 124 > one.xml
+python create.py --xml-file two.xml -a foobar -t expense 12 > two.xml
+etc..
+```
+
+
diff --git a/dummy/empty.xml b/dummy/empty.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+
+<ledger>
+ <retrieved>2025-11-02T13:09:55Z</retrieved>
+ <src>playalastunas.org</src>
+ <units base="BTC">
+ <unit sym="USD">
+ <precision>2</precision>
+ <ex>10999310</ex>
+ </unit>
+ <unit sym="BTC">
+ <precision>8</precision>
+ <ex>1</ex>
+ </unit>
+ </units>
+ <resolver algo="sha256" proto="https">g33k.holbrook.no</resolver>
+ <identity keyid="f1d2d2f924e986ac86fdf7b36c94bcdf32beec15" didtype="web">nondominium.org/lash/</identity>
+ <identity keyid="f1d2d2f924e986ac86fdf7b36c94bcdf32beec15" didtype="web">holbrook.no</identity>
+ <incoming serial="231">
+ <digest algo="sha512">b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944cb5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c</digest>
+ <sig type='ed25519' keyid="58851ae2166b3f1454193e0a7e821402dd1c1a91">1f74a9c0196a025f27d4e940c4abedfa2d37504f268aea359659cb65b85bd4d7974369507950006964c93391d3d4580ab8064f6d30a62908468ef771be952e95</sig>
+ <sig type='ed25519' keyid="566c38287d3f31c7e50836cae58e426c6bccc52d">117a57c72ed210b91469307a1c2e73fe2d5ee306cd8ccf1a9db4ecb15d38ecbbfc97d62fec4ab8aadb08c531f2d1ede34cb6e4d3987bcba63322a0767e532e13</sig>
+ <real unit="BTC">
+ <asset>6323141</asset>
+ <liability>0</liability>
+ </real>
+ <virt symbol="USD">
+ <income>4213</income>
+ <expense>77718</expense>
+ <asset>11400</asset>
+ <liability>22284</liability>
+ </virt>
+ <virt symbol="BTC">
+ <income>3249191</income>
+ <expense>0</expense>
+ <asset>3249191</asset>
+ <liability>0</liability>
+ </virt>
+ </incoming>
+</ledger>
diff --git a/dummy/running.xml b/dummy/running.xml
@@ -53,7 +53,7 @@
<digest algo="sha512">777b30c8fc40aea3c717777831a05c9f29c7b6735f1573e9b0b55373c264f6f3777b30c8fc40aea3c717777831a05c9f29c7b6735f1573e9b0b55373c264f6f3</digest>
</attachment>
</data>
- <sig type='ed25519' keyid="e242ed3bffccdf271b7fbaf34ed72d089537b42f">0cf9180a764aba863a67b6d72f0918bc131c6772642cb2dce5a34f0a702f9470ddc2bf125c12198b1995c233c34b4afd346c54a2334c350a948a51b6e8b4e6b6/</sig>
+ <sig type="ed25519" keyid="b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c">0cf9180a764aba863a67b6d72f0918bc131c6772642cb2dce5a34f0a702f9470ddc2bf125c12198b1995c233c34b4afd346c54a2334c350a948a51b6e8b4e6b6</sig>
</entry>
<entry type="liability">
<data>
@@ -67,6 +67,6 @@
<description>Install AC</description>
<amount>1000000</amount>
</data>
- <sig type='ed25519' keyid="f1d2d2f924e986ac86fdf7b36c94bcdf32beec15">cc06808cbbee0510331aa97974132e8dc296aeb795be229d064bae784b0a87a5cf4281d82e8c99271b75db2148f08a026c1a60ed9cabdb8cac6d24242dac4063</sig>
+ <sig type="ed25519" keyid="7d865e959b2466918c9863afca942d0fb89d7c9ac0c99bafc3749504ded97730">cc06808cbbee0510331aa97974132e8dc296aeb795be229d064bae784b0a87a5cf4281d82e8c99271b75db2148f08a026c1a60ed9cabdb8cac6d24242dac4063</sig>
</entry>
</ledger>
diff --git a/dummy/svcontas/__init__.py b/dummy/svcontas/__init__.py
@@ -123,7 +123,7 @@ class UnitIndex:
class Entry:
# TODO: parent only 0 if serial 0
- def __init__(self, typ, amount, unit, serial, account, tx_date, ref=None, description=None, parent=None):
+ def __init__(self, typ, amount, unit, serial, account, tx_date, ref=None, description=None, parent=None, tx_datereg=None):
self.typ = typ
if isinstance(parent, str):
parent = bytes.fromhex(parent)
@@ -140,7 +140,9 @@ class Entry:
self.serial = serial
self.account = account
self.dt = tx_date
- self.dtreg = datetime.datetime.now()
+ if tx_datereg == None:
+ tx_datereg = datetime.datetime.now()
+ self.dtreg = tx_datereg
self.attachment = []
self.sigs = {}
self.description = description
@@ -161,8 +163,16 @@ class Entry:
unit = unitindex.get(o.find('unit').text)
serial = int(o.find('serial').text)
account = o.find('account').text
+ ref = o.find('ref').text
+ parent = o.find('parent').text
+ description = o.find('description')
+ if description != None:
+ description = description.text
dt = datetime.date.fromisoformat(o.find('date').text)
- r = Entry(tree.get('type'), amount, unit, serial, account, dt)
+ dtreg = datetime.datetime.strptime(o.find('dateTimeRegistered').text, '%Y-%m-%dT%H:%M:%SZ')
+ r = Entry(tree.get('type'), amount, unit, serial, account, dt, ref=ref, parent=parent, tx_datereg=dtreg, description=description)
+ for sig in tree.iter('sig'):
+ r.add_signature(sig.get('keyid'), bytes.fromhex(sig.text))
return r
@@ -176,6 +186,7 @@ class Entry:
self.unit,
self.amount,
]
+ logg.debug('serialize entry {}'.format(d))
return rencode.dumps(d)
@@ -220,7 +231,7 @@ class Entry:
data.append(o)
o = etree.Element('dateTimeRegistered')
- o.text = self.dt.strftime('%Y-%m-%dT%H:%M:%SZ')
+ o.text = self.dtreg.strftime('%Y-%m-%dT%H:%M:%SZ')
data.append(o)
o = etree.Element('account')
@@ -233,7 +244,7 @@ class Entry:
data.append(o)
o = etree.Element('amount')
- o.text = self.account
+ o.text = str(self.amount)
data.append(o)
tree.append(data)
@@ -319,6 +330,7 @@ class Ledger:
wallet = DemoWallet(publickey=b)
v = entry.sum()
r = wallet.verify(v, sig)
+ logg.debug('having sig {}'.format(r.hex()))
return True
@@ -328,6 +340,7 @@ class Ledger:
self.running[entry.unit].apply_entry(entry)
try:
entries = self.entries[entry.serial]
+ logg.debug('------------------------ {}'.format(entries))
except KeyError:
self.entries[entry.serial] = []
entries = self.entries[entry.serial]
@@ -367,13 +380,18 @@ class Ledger:
r.running[sym] = RunningTotal(sym, unitindex, income=income, expense=expense, asset=asset, liability=liability)
logg.debug(r.running[sym])
+ r.apply_tree(tree)
return r.check()
def apply_tree(self, tree):
for v in tree.iter('entry'):
+ logg.debug('processing entry {}'.format(v))
o = Entry.from_tree(v, self.uidx)
- self.entries[o.serial] = o
+ self.check_sigs(o)
+ if self.entries.get(o.serial) == None:
+ self.entries[o.serial] = []
+ self.entries[o.serial].append(o)
self.running[o.unit].apply_entry(o)
def to_tree(self):