usawa

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

commit 90b84aa7e785b839d67b1976c990eac29db7fc90
parent aa006873c4b84f9ed0ef8646e9787e1d9cfaa3c6
Author: lash <dev@holbrook.no>
Date:   Thu,  6 Nov 2025 01:41:51 +0000

WIP add signature verifier

Diffstat:
MREADME | 20+++++++++++++++-----
Adummy/empty.xml | 40++++++++++++++++++++++++++++++++++++++++
Mdummy/running.xml | 4++--
Mdummy/svcontas/__init__.py | 30++++++++++++++++++++++++------
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):