commit a2b4cfe6990fd3fa242bafc1929369fe7b694444
parent fb90efce6f8ea5950fb6cb5bd952d5cd48a4fae2
Author: lash <dev@holbrook.no>
Date: Sat, 17 Jan 2026 09:57:22 +0000
Start writing texinfo docs
Diffstat:
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,