usawa

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

commit a2b4cfe6990fd3fa242bafc1929369fe7b694444
parent fb90efce6f8ea5950fb6cb5bd952d5cd48a4fae2
Author: lash <dev@holbrook.no>
Date:   Sat, 17 Jan 2026 09:57:22 +0000

Start writing texinfo docs

Diffstat:
Adummy/doc/appendix.texi | 155+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adummy/doc/elements.texi | 0
Adummy/doc/index.texi | 24++++++++++++++++++++++++
Adummy/doc/internals.texi | 77+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adummy/doc/intro.texi | 3+++
Adummy/doc/xml.texi | 25+++++++++++++++++++++++++
Mdummy/usawa/data/schema.xsd | 2+-
Adummy/usawa/data/usawa.ini | 3+++
Mdummy/usawa/ledger.py | 4++--
9 files changed, 290 insertions(+), 3 deletions(-)

diff --git a/dummy/doc/appendix.texi b/dummy/doc/appendix.texi @@ -0,0 +1,155 @@ +@anchor xml_schema +@appendix XML schema + +@example +<?xml version="1.0" ?> + +<xs:schema xmlns:xs = "http://www.w3.org/2001/XMLSchema" + targetNamespace = "http://usawa.defalsify.org/" + xmlns = "http://usawa.defalsify.org/" + elementFormDefault = "qualified"> + + <xs:element name="ledger"> + <xs:complexType> + <xs:sequence> + <xs:element name="uuid" type="xs:string" minOccurs="0" maxOccurs="1" /> + <xs:element name="topic" type="xs:string" /> <xs:element name="generated" type="xs:dateTime" /> <xs:element name="src" type="xs:string" minOccurs="1" maxOccurs="1" /> + <xs:element name="units" type="Units" minOccurs="1" maxOccurs="1" /> + <xs:element name="resolver" type="Resolver" minOccurs="0" maxOccurs="unbounded" /> + <xs:element name="identity" type="Identity" minOccurs="1" maxOccurs="unbounded" /> + <xs:element name="incoming" type="Incoming" minOccurs="0" maxOccurs="1" /> + <xs:element name="entry" type="Entry" minOccurs="0" maxOccurs="unbounded" /> + </xs:sequence> + <xs:attribute name="version" type="xs:integer" /> + </xs:complexType> + </xs:element> + + <xs:complexType name="Incoming"> + <xs:sequence> + <xs:element name="real" type="Balance" minOccurs="1" maxOccurs="unbounded" /> + <xs:element name="virt" type="Balance" minOccurs="0" maxOccurs="unbounded" /> + <xs:element name="digest" type="Digest" minOccurs="1" maxOccurs="1"/> + <xs:element name="sig" type="Signature" minOccurs="1" maxOccurs="unbounded" /> + </xs:sequence> + <xs:attribute name="serial" type="xs:positiveInteger" /> + </xs:complexType> + + <xs:complexType name="Balance"> + <xs:sequence> + <xs:element name="income" type="xs:integer" minOccurs="0"/> + <xs:element name="expense" type="xs:integer" minOccurs="0" /> + <xs:element name="asset" type="xs:integer" /> + <xs:element name="liability" type="xs:integer" /> + </xs:sequence> + <xs:attribute name="unit" type="xs:string" /> + </xs:complexType> + + <xs:complexType name="Units"> + <xs:sequence> + <xs:element name="unit" type="Unit" minOccurs="1" maxOccurs="unbounded" /> + </xs:sequence> + <xs:attribute name="base" type="xs:string" /> + </xs:complexType> + + <xs:complexType name="Digest"> + <xs:simpleContent> + <xs:extension base="xs:string"> + <xs:attribute name="algo" type="xs:string" /> + </xs:extension> + </xs:simpleContent> + </xs:complexType> + + <xs:complexType name="Signature"> + <xs:simpleContent> + <xs:extension base="xs:string"> + <xs:attribute name="keyid" type="xs:string" /> + <xs:attribute name="type" type="xs:string" /> + </xs:extension> + </xs:simpleContent> + </xs:complexType> + + <xs:complexType name="Unit"> + <xs:sequence> + <xs:element name="precision" type="xs:positiveInteger" maxOccurs="1" minOccurs="1" /> + <xs:choice> + <xs:element name="exchange" type="xs:positiveInteger" maxOccurs="1" minOccurs="1" /> + <xs:sequence> + <xs:element name="rate" type="Rate" minOccurs="1" maxOccurs="unbounded" /> + </xs:sequence> + </xs:choice> + </xs:sequence> + <xs:attribute name="sym" type="xs:string" /> + </xs:complexType> + + <xs:complexType name="Rate"> + <xs:sequence> + <xs:choice> + <xs:element name="at" type="xs:date" /> + <xs:element name="at" type="xs:dateTime" /> + </xs:choice> + <xs:element name="vs" type="xs:string" /> + <xs:element name="value" type="xs:integer" /> + </xs:sequence> + </xs:complexType> + + <xs:complexType name="Identity"> + <xs:simpleContent> + <xs:extension base="xs:string"> + <xs:attribute name="keyid" type="xs:string" /> + <xs:attribute name="didtype" type="xs:string" /> + </xs:extension> + </xs:simpleContent> + </xs:complexType> + + <xs:complexType name="Resolver"> + <xs:simpleContent> + <xs:extension base="xs:string"> + <xs:attribute name="algo" type="xs:string" /> + <xs:attribute name="proto" type="xs:string" /> + </xs:extension> + </xs:simpleContent> + </xs:complexType> + + <xs:complexType name="Entry"> + <xs:sequence> + <xs:element name="data" type="EntryData" /> + <xs:element name="sig" type="Signature" minOccurs="1" maxOccurs="unbounded" /> + </xs:sequence> + <!-- TODO: attribute enum --> + </xs:complexType> + + <xs:complexType name="EntryData"> + <xs:sequence> + <xs:element name="parent" type="xs:string" /> + <xs:element name="uuid" type="xs:string" minOccurs="0" maxOccurs="1" /> + <xs:element name="ref" type="xs:string" /> + <xs:element name="serial" type="xs:positiveInteger" /> + <xs:element name="unit" type="xs:string" /> + <xs:element name="date" type="xs:date" /> + <xs:element name="dateTimeRegistered" type="xs:dateTime" /> + <xs:element name="src" type="EntryPart"/> + <xs:element name="dst" type="EntryPart"/> + <xs:element name="attachment" type="Attachment" minOccurs="0" maxOccurs="unbounded" /> + </xs:sequence> + </xs:complexType> + + <xs:complexType name="EntryPart"> + <xs:sequence> + <xs:element name="account" type="xs:string" /> + <xs:element name="amount" type="xs:nonNegativeInteger" /> + </xs:sequence> + <xs:attribute name="type" type="xs:string" /> + </xs:complexType> + + <xs:complexType name="Attachment"> + <xs:sequence> + <xs:element name="uuid" type="xs:string" minOccurs="0" maxOccurs="1" /> + <xs:element name="slug" type="xs:string" /> + <xs:element name="description" type="xs:string" /> + <xs:element name="digest" type="Digest" /> + </xs:sequence> + <xs:attribute name="mime" type="xs:string" /> + </xs:complexType> +</xs:schema> +@end example + diff --git a/dummy/doc/elements.texi b/dummy/doc/elements.texi diff --git a/dummy/doc/index.texi b/dummy/doc/index.texi @@ -0,0 +1,24 @@ +\input texinfo +@settitle usawa + +@copying +Documentation released 2026 under CC-BY-SA +@end copying + +@titlepage +@title usawa +@author Louis Holbrook +@end titlepage + +@c +@contents + +@ifnottex +@node Top +@top Introduction +@end ifnottex + +@include intro.texi +@include xml.texi +@include internals.texi +@include appendix.texi diff --git a/dummy/doc/internals.texi b/dummy/doc/internals.texi @@ -0,0 +1,77 @@ +@chapter Internals + + +@section Serializations + +@subsection Ledger + +The serialization of ledger is used to generate signature material used in the XML state header. + +Serialization uses the rencode format, and all individual elements are elements in a list. + +The list elements are generated as follows: + +@enumerate +@item @strong{topic}, literal bytes. +@item The current state @strong{serial}, LEB128s encoded. +@item The current state @strong{digest}, 64 bytes (sha512). +@item @strong{timestamp} as big endian 32-bit value. +@item Serialization of the @strong{Unit Index}. +@item Serialization of the @strong{Access Control List}. +@item Serialization of the @strong{Running Total}. +@end enumerate + + +@subsection Unit Index + +A collection of units of account, defining their value precision level aswell as exchange rates. + +Serialization uses the rencode format, and all individual elements are elements in a list. + +The list elements are generated as follows: + +@enumerate +@item The base unit symbol, UTF-8 byte value. +@item List of unit definitions, see below +@end enumerate + + +@subsubsection Serialization of unit definitions + +The list elements are generated as follows: + +@enumerate +@item The unit symbol to define. +@item The unit precision level, as an 8-bit unsigned integer value. +@item Exchange rate, as a 64 bit unsigned integer value. +@end enumerate + + +@subsection Access Control List + +(TODO: rename) + +Defines known public keys and what each key can be trusted to sign for. + +The list elements are themselves lists, the latter generated as follows: + +@enumerate +@item Public key, literal, hex-encoded. +@item The persmissions bitflag array, currently 4 bytes. literal. +@end enumerate + + + +@subsection Running Total + +Keeps the state of accounts for each used unit. + +The list elements are generated as follows: + +@enumerate +@item The unit symbol the running totla is kept for. +@item The income account balance, positive or negative, LEB128s encoded. +@item The expense account balance, positive or negative, LEB128s encoded. +@item The asset account balance, positive or negative, LEB128s encoded. +@item The liability account balance, positive or negative, LEB128s encoded. +@end enumerate diff --git a/dummy/doc/intro.texi b/dummy/doc/intro.texi @@ -0,0 +1,3 @@ +@chapter Introduction + + diff --git a/dummy/doc/xml.texi b/dummy/doc/xml.texi @@ -0,0 +1,25 @@ +@chapter Data format + +The canonical ledger data format is XML. + +The XML schema is designed to allow embedding of all data necessary to verify integrity signatures, including exchange rates between units of account. + +Order of elements are important in the XML document. The schema is cited in @xref{xml_schema, appendix A}. + + +@section Ledger header + +The responsibility of the ledger header is to give the consumer the necessary resources to validate the entries in the ledger. + +It includes: + +@itemize +@item The document version, indicating which version of schema to use. +@item Topic, which uniquely identifies the legder instance. +@item Generation date and time of the XML document. +@item Index of units of account used in the following entries. @ref{unit_index,Unix Index} +@item The public key identities whose signatures appear in the document. @ref{identity,Public Key Identities}. +@item Details on resolver services that can be used to expand assets references by digests. See @xref{resolver, Resolvers} and @xref{assets, Referencing assets}. +@item Ledger state, under the element @code{incoming}, defining the digest of the position of the entry chain the ledger document starts at. @ref{incoming, Ledger State}. +@item Signatures that may authenticate the ledger state. +@end itemize diff --git a/dummy/usawa/data/schema.xsd b/dummy/usawa/data/schema.xsd @@ -9,7 +9,7 @@ <xs:complexType> <xs:sequence> <xs:element name="uuid" type="xs:string" minOccurs="0" maxOccurs="1" /> - <xs:element name="topic" type="xs:string" /> <xs:element name="retrieved" type="xs:dateTime" /> <xs:element name="src" type="xs:string" minOccurs="1" maxOccurs="1" /> + <xs:element name="topic" type="xs:string" /> <xs:element name="generated" type="xs:dateTime" /> <xs:element name="src" type="xs:string" minOccurs="1" maxOccurs="1" /> <xs:element name="units" type="Units" minOccurs="1" maxOccurs="1" /> <xs:element name="resolver" type="Resolver" minOccurs="0" maxOccurs="unbounded" /> <xs:element name="identity" type="Identity" minOccurs="1" maxOccurs="unbounded" /> diff --git a/dummy/usawa/data/usawa.ini b/dummy/usawa/data/usawa.ini @@ -0,0 +1,3 @@ +[valkey] +host = +port = diff --git a/dummy/usawa/ledger.py b/dummy/usawa/ledger.py @@ -277,7 +277,7 @@ class Ledger: else: topic = self.topic.hex() o.text = topic - o = lxml.etree.SubElement(tree, NSPREFIX + 'retrieved', nsmap=nsmap()) + o = lxml.etree.SubElement(tree, NSPREFIX + 'generated', nsmap=nsmap()) self.dt = datetime.datetime.now() o.text = to_datestring(self.dt) #self.tree.append(o) @@ -669,7 +669,7 @@ class Ledger: totals.append(v) d = [ self.topic, - self.serial.to_bytes(8, byteorder='big'), + varints.leb128s.encode(self.serial), self.cur, ts_bytes, units,