usawa

Signed, immutable accounting.
Log | Files | Refs | Submodules | LICENSE

commit 91a81dbd00ddb8f4c678860fcad21611ef3c836f
parent 4bd8ca79c1e66e55a1cc5634c4fb3b7c003f817a
Author: lash <dev@holbrook.no>
Date:   Sun, 29 Mar 2026 00:34:55 -0600

Add context package, add keystore to entrystore

Diffstat:
Mdummy/usawa/context.py | 123+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Mdummy/usawa/store.py | 72++++++++++++++++++++++++++++++++++++------------------------------------
2 files changed, 157 insertions(+), 38 deletions(-)

diff --git a/dummy/usawa/context.py b/dummy/usawa/context.py @@ -1,2 +1,121 @@ -class Context: - pass +from whee.valkey import ValkeyStore +from whee.fs import FsStore +from usawa import DemoWallet, Ledger +from usawa.account import AccountIndex +from usawa.store import LedgerStore, EntryStore, KeyStore +from usawa.resolve.fs import FSResolver + + +class UsawaContext: + + def __init__(self, cfg): + self.cfg = cfg + self.db = None + self.ledger = None + self.ledger_path_in = None + self.ledger_path_out = None + self.uidx = None + self.wallet = None + self.resolver = None + self.store = None + self.keystore = None + self.aidx = None + self.o = {} + + + def set(self, k, v): + self.o[k] = v + + + def get(self, k): + return self.o[k] + + + def init(self, args, store_scope=None): + v = None + try: + v = args.i + except AttributeError: + pass + self.ledger_path_in = self.cfg.get('MAIN_LEDGER_FILE', v) + v = None + try: + v = args.o + except AttributeError: + pass + self.ledger_path_out = self.cfg.get('MAIN_LEDGER_FILE', v) + if self.ledger_path_out == None: + self.ledger_path_out = self.ledger_path_in + if self.ledger_path_in != None: + self.load_ledger() + self.create_store(store_scope=store_scope) + self.create_resolver() + self.load_accounts() + self.load_wallet() + + + def load_wallet(self): + if self.wallet != None: + raise AttributeError('wallet set') + ops = int(self.cfg.get('WALLET_OPSLIMIT', 0)) + mem = int(self.cfg.get('WALLET_MEMLIMIT', 0)) + pw = self.cfg.get('WALLET_KEY_PASSPHRASE') + self.wallet = self.keystore.get_key(DemoWallet, passphrase=pw, opslimit=ops, memlimit=mem) + if self.ledger != None: + self.ledger.set_wallet(self.wallet) + + + def load_ledger(self): + if self.ledger != None: + raise AttributeError('ledger set') + self.ledger = Ledger.from_file(self.ledger_path_in) + self.uidx = self.ledger.uidx + if self.wallet != None: + self.ledger.set_wallet(self.wallet) + + + def load_accounts(self): + s = self.cfg.get('ACCOUNTS_FILE') + if s: + self.aidx = AccountIndex.from_file(self.uidx, s) + else: + self.aidx = AccountIndex(uidx) + if self.cfg.true('ACCOUNTS_STRICT'): + self.aidx.lock() + + + def create_store(self, store_scope=None): + if store_scope == None: + store_scope = 'ledger' + if self.store != None: + raise AttributeError('store set') + if store_scope == 'ledger': + if self.ledger == None: + raise AttributeError('ledger required for ledger store scope') + if self.cfg.get('STORE_TYPE') == 'valkey': + dbid = self.cfg.get('VALKEY_ID') + host = self.cfg.get('VALKEY_HOST') + port = self.cfg.get('VALKEY_PORT') + self.db = ValkeyStore('', host=host, port=port) + elif self.cfg.get('STORE_TYPE') == 'fs': + base = self.cfg.get('FSSTORE_BASE') + self.db = FsStore(base=base, dbname='usawa') + if store_scope == 'ledger': + self.store = LedgerStore(self.db, self.ledger) + self.keystore = self.store + elif store_scope == 'asset' or store_score == 'entry': + self.store = EntryStore(self.db) + self.keystore = KeyStore(self.db) + + + def create_resolver(self, resolver_type='fs'): + if resolver_type != 'fs': + raise NotImplementedError('only fs resolver available') + resolver_path = self.cfg.get('FS_RESOLVER_STORE_PATH') + if resolver_path: + self.resolver = FSResolver(resolver_path) + else: + logg.debug('missing resolver') + + + diff --git a/dummy/usawa/store.py b/dummy/usawa/store.py @@ -210,7 +210,42 @@ class KeyStore(BaseStore): return wallet_class.from_export(r, passphrase=passphrase, opslimit=opslimit, memlimit=memlimit) -class EntryStore(BaseStore): +class AssetStore(BaseStore): + + """Add an entry attachment asset to the store. + + :param asset: Asset containing digest to restore. + :type asset: usawa.Asset + :raises: FileExistsError if entry is already in store. + """ + def add_asset(self, asset, overwrite=False): + k = pfx_asset(asset) + v = asset.serialize() + self.db.put(k, v, exist_ok=overwrite) + v = k + k = pfx_asset_index(asset) + self.db.put(k, v, exist_ok=True) + + + """Restore an entry attachment asset from the store. + """ + def get_asset(self, asset): + k = pfx_asset(asset) + v = self.db.get(k) + digest = asset.get_digest(binary=True) + return Asset.deserialize(v, digest) + + + """Restore an entry attachment asset from the store using the reference index. + """ + def get_asset_indexed(self, asset): + k = pfx_asset_index(asset) + k = self.db.get(k) + v = self.db.get(k) + return Asset.deserialize(v, k[1:]) + + +class EntryStore(KeyStore): # TODO: this will overwrite the draft when the entry has a serial, but on check is being performed that the ledger entry was actually added. @@ -282,41 +317,6 @@ class EntryStore(BaseStore): return entry -class AssetStore(BaseStore): - - """Add an entry attachment asset to the store. - - :param asset: Asset containing digest to restore. - :type asset: usawa.Asset - :raises: FileExistsError if entry is already in store. - """ - def add_asset(self, asset, overwrite=False): - k = pfx_asset(asset) - v = asset.serialize() - self.db.put(k, v, exist_ok=overwrite) - v = k - k = pfx_asset_index(asset) - self.db.put(k, v, exist_ok=True) - - - """Restore an entry attachment asset from the store. - """ - def get_asset(self, asset): - k = pfx_asset(asset) - v = self.db.get(k) - digest = asset.get_digest(binary=True) - return Asset.deserialize(v, digest) - - - """Restore an entry attachment asset from the store using the reference index. - """ - def get_asset_indexed(self, asset): - k = pfx_asset_index(asset) - k = self.db.get(k) - v = self.db.get(k) - return Asset.deserialize(v, k[1:]) - - class LedgerStore(EntryStore, AssetStore, KeyStore): """Wrapper for an implementation of the whee store that handles encoding of ledgers and entries.