usawa

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

commit 53ae6759f6655f0561976b54e77b32dc6d213108
parent a8ee942152ad43bebd79f8ce596c9ebdbaf4b994
Author: lash <dev@holbrook.no>
Date:   Wed, 11 Feb 2026 14:52:28 +0000

Enable multiple commands in service

Diffstat:
Mdummy/tests/handler.py | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Mdummy/usawa/runnable/server.py | 6++----
Mdummy/usawa/service.py | 55+++++++++++++++++++++++++++++++++++++------------------
3 files changed, 96 insertions(+), 24 deletions(-)

diff --git a/dummy/tests/handler.py b/dummy/tests/handler.py @@ -16,18 +16,73 @@ logg = logging.getLogger() testdir = os.path.realpath(os.path.dirname(__file__)) +def zero_handler(v): + logg.debug('zero handler arg 0x{}'.format(v.hex())) + return 0 + + +def create_handler(): + handler = Handler() + handler.register(0, zero_handler) + return handler + + class TestHandler(unittest.TestCase): def setUp(self): self.store = MemStore() - self.handler = Handler() def test_handler(self): + handler = create_handler() b = b'\x00\x00\x00\x00' - r = self.handler.scan(b) + r = handler.scan(b) self.assertEqual(r, 0) + def test_handler_pair_invalid(self): + handler = create_handler() + b = b'\x00\x00\x00\x00\x09\x00\x00\x00' + r = handler.scan(b) + self.assertEqual(r, 0) + with self.assertRaises(ValueError): + handler.scan(b'') + + + def test_handler_twopass(self): + handler = create_handler() + b = b'\x00\x00\x00' + r = handler.scan(b) + self.assertEqual(r, 1) + b = b'\x00' + r = handler.scan(b) + self.assertEqual(r, 0) + + + def test_handler_twopass_pair(self): + handler = create_handler() + b = b'\x00\x00\x00\x00\x09\x00\x00' + r = handler.scan(b) + self.assertEqual(r, 0) + b = b'\x00' + r = handler.scan(b'') + self.assertEqual(r, 1) + with self.assertRaises(ValueError): + handler.scan(b'\x00') + + + def test_handler_twopass_pair(self): + handler = create_handler() + b = b'\x00\x00\x00\x00\x09\x00\x00' + r = handler.scan(b) + self.assertEqual(r, 0) + b = b'\x00' + r = handler.scan(b'') + self.assertEqual(r, 1) + with self.assertRaises(ValueError): + handler.scan(b'\x00') + + + if __name__ == '__main__': unittest.main() diff --git a/dummy/usawa/runnable/server.py b/dummy/usawa/runnable/server.py @@ -4,7 +4,6 @@ import argparse from usawa import Ledger, Entry, EntryPart, DemoWallet, ACL, UnitIndex, load from usawa.context import Context -from usawa.store import LedgerStore from usawa.service import Handler, SocketServer from whee.valkey import ValkeyStore @@ -34,10 +33,9 @@ def main(): ledger_tree = load(arg.ledger_xml_file) uidx = UnitIndex.from_tree(ledger_tree) ledger = Ledger.from_tree(ledger_tree, acl=acl) + db = ValkeyStore('') - store = LedgerStore(db, ledger) - - srv = SocketServer(store) + srv = SocketServer(db, ledger, acl=acl) #srv.start() diff --git a/dummy/usawa/service.py b/dummy/usawa/service.py @@ -1,24 +1,33 @@ import logging import socket +from usawa.store import LedgerStore + logg = logging.getLogger('handler') class Handler: + cmd_len = 1 + len_len = 3 + def __init__(self): self.cmd = None self.buf = b'' self.c = 0 self.l = 0 + self.r = None self.state = 0 + self.h = {} + + + def register(self, k, fn): + self.h[k] = fn def scan(self, v): - self.buf = v - if len(v) == 0: - return -1 - if self.cmd == None: + self.buf += v + if self.state == 0: r = self.handle_cmd() if r > 0: return r @@ -26,9 +35,7 @@ class Handler: return False if self.handle_collect() > 0: return False - if self.cmd == 0: - return self.handle_getlastserial() - raise ValueError() + return self.handle() def handle_cmd(self): @@ -36,6 +43,7 @@ class Handler: self.c = 1 self.l = -1 self.state = 1 + self.r = None return self.handle_len() @@ -45,39 +53,53 @@ class Handler: def handle_len(self): + if self.state != 1: + return -1 (l, v) = self.__remainder() if l == 0: return 0 if l < 3: return 3 - l + v = self.buf[1:4] self.l = int.from_bytes(v, byteorder='big') self.c += 3 + self.state = 2 + logg.debug('cmd {} has len {}'.format(self.cmd, self.l)) return 0 def handle_collect(self): + if self.state != 2: + return -1 (l, v) = self.__remainder() self.c += l - c = self.c - 3 + c = self.c - 4 if c >= l: - self.r = True - self.c = l + 3 + c = self.l + 4 + self.state = 3 + self.r = self.buf[4:c] + self.buf = self.buf[c:] + self.c = 0 c = l logg.debug('have cmd {} len {} arg {}'.format(self.cmd, self.l, self.buf[3:self.c].hex())) return l - c - def handle_getlastserial(self): - logg.debug('would get last serial') + def handle(self): self.state = 0 - return 0 + fn = self.h.get(self.cmd) + if fn == None: + raise ValueError() + logg.debug('handling cmd {} arg 0x{} rest buffer 0x{}'.format(self.cmd, self.r.hex(), self.buf.hex())) + return fn(self.r) class SocketServer: - def __init__(self, store): + def __init__(self, db, ledger, acl=None): self.scks = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.store = store + self.store = LedgerStore(db, ledger) + self.acl = acl def start(self): @@ -107,6 +129,3 @@ class SocketServer: parse(bytes(data)) data.append(v) logg.debug('read {}: {}'.format(len(b), b.hex())) - - -