kee

Offline IOU signer with QR as transport
git clone https://holbrook.no/src/kee
Info | Log | Files | Refs | README | LICENSE

commit ca4a2602a8087d75a09ffa0a8f2d3b98e57bedf2
parent b53510bd7b7105677d983717d8d237b9d2dacc65
Author: lash <dev@holbrook.no>
Date:   Mon, 20 May 2024 15:15:29 +0100

WIP implement llog and rerr

Diffstat:
M.gitignore | 3+++
MMakefile | 2++
Msrc/Makefile | 6+++---
Msrc/asn1/Makefile | 6+++---
Msrc/aux/Makefile | 23++++++-----------------
Msrc/camera.c | 1-
Msrc/content.c | 5++---
Msrc/db.c | 5++---
Asrc/debug.c | 15+++++++++++++++
Msrc/debug.h | 18++++++++----------
Msrc/digest.c | 3++-
Msrc/dn.c | 2+-
Msrc/err.h | 59+++++++++++++++++++++--------------------------------------
Msrc/gpg.c | 17+++++++++++++++--
Msrc/gpg.h | 13+++++++++++++
Msrc/gtk/context.c | 3+--
Msrc/gtk/debug.c | 2++
Msrc/gtk/scan.c | 2+-
Msrc/gtk/view.c | 2+-
Msrc/ledger.c | 3++-
Msrc/ledger.h | 4++++
Msrc/settings.c | 3++-
Msrc/tests/Makefile | 8+++++---
Dsrc/tests/debug.c | 7-------
Asrc/tests/debugdebug.c | 15+++++++++++++++
Msrc/tests/testutil.c | 9++++++++-
Msrc/transport.c | 4+++-
Msrc/transport.h | 3+++
Dtestdata_ng.py | 397-------------------------------------------------------------------------------
29 files changed, 143 insertions(+), 497 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -5,3 +5,6 @@ testdata_* **/test_* **/*.out src/aux/include +testdata +src/asn1/schema_*.c +src/asn1/generate_asn1 diff --git a/Makefile b/Makefile @@ -5,6 +5,8 @@ core: subs gtk: core make -C src/gtk +src: subs + subs: glade make -C src diff --git a/src/Makefile b/src/Makefile @@ -7,7 +7,7 @@ LDFLAGS += $(LIBS) #all: aux resource $(OBJS) # $(CC) $(CFLAGS) main.c -o a.out $(OBJS) $(LDFLAGS) aux/varint/varint.o #all: aux $(OBJS) -all: asn $(OBJS) +all: aux asn $(OBJS) asn: make -C asn1 compile @@ -16,8 +16,8 @@ asn: %.o: %.c $(CC) $(CFLAGS) -c $< -o $@ $(LDFLAGS) -#aux: -# make -C aux +aux: + make -C aux clean: rm -vf *.o diff --git a/src/asn1/Makefile b/src/asn1/Makefile @@ -5,7 +5,7 @@ LDFLAGS += $(LIBS) all: compile src: - $(CC) $(CFLAGS) generate.c -o generate $(LDFLAGS) + $(CC) $(CFLAGS) generate.c -o generate_asn1 $(LDFLAGS) %.o: %_asn1_tab.c $(CC) $< -o $* $(LDFLAGS) @@ -13,11 +13,11 @@ src: compile: generate schema_entry_asn1_tab.o generate: src - ./generate + ./generate_asn1 clean: rm -vf *.o rm -vf *_asn1_tab.c - rm -vf generate + rm -vf generate_asn1 .PHONY: clean diff --git a/src/aux/Makefile b/src/aux/Makefile @@ -1,20 +1,9 @@ -# TODO: unify destinations +all: lash +lash: llog rerr -all: varint cmime +llog: + make -C llog -varint: - make -C varint - -cmime: - mkdir -p libcmime/build - cd libcmime/build && cmake .. - make -C libcmime/build - mkdir -vp include - cd include && ln -vsf ../libcmime/src cmime - -clean: - make -C varint clean - make -C libcmime/build clean - -.PHOBY: clean +rerr: + make -C rerr diff --git a/src/camera.c b/src/camera.c @@ -7,7 +7,6 @@ #include <dirent.h> #include <sys/types.h> -#include "err.h" #include "debug.h" #include "camera.h" diff --git a/src/content.c b/src/content.c @@ -1,10 +1,9 @@ #include <stdlib.h> #include <string.h> - -#include "cmime.h" +#include <rerr.h> +#include <cmime.h> #include "content.h" -#include "err.h" #include "defs.h" #include "digest.h" diff --git a/src/db.c b/src/db.c @@ -4,9 +4,10 @@ #include <gcrypt.h> #include <time.h> +#include <rerr.h> + #include "db.h" #include "digest.h" -#include "err.h" #include "endian.h" #include "debug.h" #include "hex.h" @@ -53,8 +54,6 @@ int db_start(struct db_ctx *ctx) { int db_add(struct db_ctx *ctx, char *key, size_t key_len, char *data, size_t data_len) { int r; - char s[1024]; - size_t c; ctx->k.mv_data = key; ctx->k.mv_size = key_len; diff --git a/src/debug.c b/src/debug.c @@ -0,0 +1,15 @@ +#include "debug.h" + +void debug_log(enum debugLevel level, const char *s); + +void debug_logerr(enum lloglvl_e lvl, char *msg, int err) { + char *e; + char *s; + + s = rerrpfx(err); + e = llog_new_ns(lvl, msg, s); + e = llog_add_n("errcode", err); + s = rerrstrv(err); + e = llog_add_s("err", s); + debug_log(lvl, e); +} diff --git a/src/debug.h b/src/debug.h @@ -1,5 +1,9 @@ -#ifndef _DEBUG_H -#define _DEBUG_H +#ifndef DEBUG_H_ +#define DEBUG_H_ + +// provides: +#include <llog.h> +#include <rerr.h> /** * \brief Debug levels for simple log output. @@ -19,10 +23,6 @@ enum debugLevel { DEBUG_TRACE, }; -#ifdef __cplusplus -extern "C" { -#endif - /** * * \brief Implementer logs constant string according to given log level. @@ -30,10 +30,8 @@ extern "C" { * \param level Debug level * \param s String to log */ +//void debug_log(enum debugLevel level, const char *s); void debug_log(enum debugLevel level, const char *s); - -#ifdef __cplusplus -} -#endif +void debug_logerr(enum lloglvl_e, char *s, int err); #endif diff --git a/src/digest.c b/src/digest.c @@ -1,6 +1,7 @@ #include <gcrypt.h> -#include "err.h" +#include <rerr.h> + #include "digest.h" diff --git a/src/dn.c b/src/dn.c @@ -2,8 +2,8 @@ #include <string.h> #include <ldap.h> +#include <rerr.h> -#include "err.h" #include "dn.h" struct kee_dn_t* kee_dn_init(struct kee_dn_t *dn, size_t cap) { diff --git a/src/err.h b/src/err.h @@ -1,38 +1,21 @@ -#ifndef _KEE_ERR_H -#define _KEE_ERR_H - -/** - * - * Error codes within context of the kee application and backend. - * - */ -enum keeError { - /// No error so far within current context - ERR_OK, - /// General failure code - ERR_FAIL, - /// Last attempt to unlock key failed - ERR_KEY_UNLOCK, - /// Usage of key for signature has been rejected (by user) - ERR_KEY_REJECT, - /// Last input matches entry that already exists in storage - ERR_INPUT_CORRUPT, - /// Last input changes entry that already exists in storage, but was not allowed - ERR_INPUT_DUP, - /// Last input changes entry that already exists in storage, but was not allowed - ERR_INPUT_PROTECT, - /// Crypto backend unavailable - ERR_NOCRYPTO, - /// Crypto resource fail - ERR_NOKEY, - /// Crypto authentication fail - ERR_KEYFAIL, - ERR_ALREADY_SIGNED, - ERR_INVALID_CMD, - ERR_QR_MISSING, - ERR_QR_INVALID, - ERR_SPACE, - ERR_UNSUPPORTED, -}; - -#endif // _KEE_ERR_H +//#ifndef KEE_ERR_H_ +//#define KEE_ERR_H_ +// +///** +// * +// * Error codes within context of the kee application and backend. +// * +// */ +// +//#define ERR_OK 0x0 +//#define ERR_FAIL 0x1 +//#define ERR_UNSUPPORTED 0x2 +// +//#ifndef RERR_N_PFX +//#define RERR_N_PFX 0 +//#endif +// +//void rerr_register(int pfx, char *label, void *start); +//char* rerrstr(int code, char *buf); +// +//#endif // _KEE_ERR_H diff --git a/src/gpg.c b/src/gpg.c @@ -6,7 +6,8 @@ #include <unistd.h> #include <errno.h> -#include "err.h" +#include <rerr.h> + #include "debug.h" #include "gpg.h" #include "hex.h" @@ -14,11 +15,19 @@ #define BUFLEN 1024 * 1024 +#ifdef RERR +char *_rerr[5] = { + "Crypto backend", + "Auth fail", + "Unlock fail", + "Sign reject", + "Resource fail", +}; +#endif const char *gpgVersion = NULL; const char sign_test[64]; - size_t get_padsize(size_t insize, size_t blocksize) { size_t c; size_t l; @@ -479,6 +488,10 @@ int gpg_store_digest(struct gpg_store *gpg, char *out, const char *in) { /// \todo handle path length limit void gpg_store_init(struct gpg_store *gpg, const char *path) { +#ifdef RERR + rerr_register(RERR_PFX_GPG, "gpg", _rerr); +#endif + char *p; size_t c; memset(gpg, 0, sizeof(struct gpg_store)); diff --git a/src/gpg.h b/src/gpg.h @@ -18,6 +18,19 @@ #define ENCRYPT_BLOCKSIZE 4096 #endif +#define RERR_PFX_GPG 0x100 +/// Crypto backend unavailable +#define ERR_NOCRYPTO 0x101 +/// Crypto authentication fail +#define ERR_KEYFAIL 0x102 +/// Last attempt to unlock key failed +#define ERR_KEY_UNLOCK 0x103 +/// Usage of key for signature has been rejected (by user) +#define ERR_KEY_REJECT 0x104 +/// Crypto resource fail +#define ERR_NOKEY 0x105 + + enum gpg_find_mode_e { KEE_GPG_FIND_MAIN, KEE_GPG_FIND_FINGERPRINT, diff --git a/src/gtk/context.c b/src/gtk/context.c @@ -1,5 +1,6 @@ #include <string.h> +#include "debug.h" #include "context.h" #include "settings.h" #include "camera.h" @@ -9,8 +10,6 @@ #include "cadiz.h" #include "cadir.h" -#define G_LOG_DOMAIN "Kee" - int kee_context_init(struct kee_context *ctx, struct kee_settings *settings) { int r; diff --git a/src/gtk/debug.c b/src/gtk/debug.c @@ -20,3 +20,5 @@ void debug_log(enum debugLevel level, const char *s) { } g_log(G_LOG_DOMAIN, loglevel, s); } + +extern void debug_logerr(enum lloglvl_e lvl, char *msg, int err); diff --git a/src/gtk/scan.c b/src/gtk/scan.c @@ -3,8 +3,8 @@ #include <gtk/gtk.h> #include <gst/gst.h> +#include "debug.h" #include "scan.h" -#include "err.h" void scan_init(struct kee_scanner *scan, const char *device) { diff --git a/src/gtk/view.c b/src/gtk/view.c @@ -1,8 +1,8 @@ #include <gtk/gtk.h> +#include "debug.h" #include "view.h" #include "nav.h" -#include "err.h" static struct KeeView view; diff --git a/src/ledger.c b/src/ledger.c @@ -3,9 +3,10 @@ #include <libtasn1.h> #include <gcrypt.h> +#include <rerr.h> + #include "ledger.h" #include "cadiz.h" -#include "err.h" #include "debug.h" #include "digest.h" #include "strip.h" diff --git a/src/ledger.h b/src/ledger.h @@ -9,6 +9,10 @@ #include "db.h" #include "digest.h" +#define ERRR_PFX_LEDGER 0x200 +/// Ledger state has already been signed +#define ERR_ALREADY_SIGNED 0x201 + enum kee_initiator_e { NOONE, ALICE, diff --git a/src/settings.c b/src/settings.c @@ -5,7 +5,8 @@ #include <basedir.h> #include <sys/stat.h> -#include "err.h" +#include <rerr.h> + #include "debug.h" #include "settings.h" diff --git a/src/tests/Makefile b/src/tests/Makefile @@ -3,7 +3,7 @@ OBJS := $(patsubst %.c,%.o,$(filter-out util.c,$(wildcard *.c))) LINKOBJS := $(wildcard ../*.o) INCLUDES := -I.. -CFLAGS += `pkg-config --cflags gtk4 gstreamer-1.0 zbar` $(INCLUDES) -Wall +CFLAGS += `pkg-config --cflags gtk4 gstreamer-1.0 zbar` $(INCLUDES) -Wall -DRERR -DRERR_N_PREFIX=2 LIBS := `pkg-config --libs gtk4 zlib lmdb libgcrypt libxdg-basedir gstreamer-1.0 libqrencode zbar` -lb64 -llash -ltasn1 -lcmime -lldap LDFLAGS += $(LIBS) @@ -13,10 +13,11 @@ util: $(CC) $(CFLAGS) -c testutil.c -o testutil.o obj_debug: util - $(CC) $(CFLAGS) -c debug.c -o debug.o +# $(CC) $(CFLAGS) -c debug.c -o debug.o %.o: %.c - $(CC) $(CFLAGS) $< -o test_$* debug.o testutil.o $(LINKOBJS) $(LDFLAGS) +# $(CC) $(CFLAGS) $< -o test_$* debug.o testutil.o $(LINKOBJS) $(LDFLAGS) + $(CC) $(CFLAGS) $< -o test_$* testutil.o $(LINKOBJS) $(LDFLAGS) #test_run: $(wildcard test_*) # ./$< @@ -25,6 +26,7 @@ testdata: ln -sf ../../testdata testdata test_run: testdata + ./test_debugdebug ./test_cadir ./test_content ./test_sign diff --git a/src/tests/debug.c b/src/tests/debug.c @@ -1,7 +0,0 @@ -#include <stdio.h> - -#include "debug.h" - -void debug_log(enum debugLevel level, const char *s) { - fprintf(stderr, "%s\n", s); -} diff --git a/src/tests/debugdebug.c b/src/tests/debugdebug.c @@ -0,0 +1,15 @@ +#include "debug.h" + +char *_rerr[2] = { + "Epic Foo Fail", + "Epic Bar Fail", +}; + + +int main() { + rerr_init(); + rerr_register(0x100, "debugtest", _rerr); + debug_logerr(LLOG_INFO, "foo", 0x101); + + return ERR_OK; +} diff --git a/src/tests/testutil.c b/src/tests/testutil.c @@ -5,10 +5,17 @@ #include "testutil.h" #include "ledger.h" -#include "err.h" #include "content.h" #include "digest.h" #include "db.h" +#include "debug.h" + +void debug_log(enum debugLevel level, const char *s) { + fprintf(stderr, "%s\n", s); +} + +extern void debug_logerr(enum lloglvl_e lvl, char *msg, int err); + int kee_test_db(struct kee_test_t *t) { int r; diff --git a/src/transport.c b/src/transport.c @@ -1,12 +1,14 @@ #include <stddef.h> #include <stdlib.h> #include <string.h> + #include <b64/cencode.h> #include <b64/cdecode.h> #include <zlib.h> + #include "transport.h" -#include "err.h" #include "ledger.h" +#include "debug.h" static int pack_compress(char *in, size_t in_len, char *out, size_t *out_len) { diff --git a/src/transport.h b/src/transport.h @@ -5,6 +5,9 @@ #include "chunk.h" +#define ERRR_PFX_TRANSPORT 0x300 +#define ERR_INVALID_CMD 0x301 + enum kee_transport_mode_e { KEE_TRANSPORT_RAW, KEE_TRANSPORT_BASE64, diff --git a/testdata_ng.py b/testdata_ng.py @@ -1,397 +0,0 @@ -import os -import sys -import io -import logging -import hashlib -from Crypto.Cipher import ChaCha20_Poly1305 -from Crypto.PublicKey import ECC -import Crypto.IO.PKCS8 -import Crypto.Util.asn1 -import lmdb -import time -import shutil -import email.message -import random -from faker import Faker -from faker.providers import lorem -import varint - -logging.basicConfig(level=logging.DEBUG) -logg = logging.getLogger() - -fake = Faker() -fake.add_provider(lorem) - -SIGNS_ALICE_CREDIT_DELTA_NEGATIVE = 1 << 0 -SIGNS_BOB_CREDIT_DELTA_NEGATIVE = 1 << 1 -SIGNS_ALICE_COLLATERAL_DELTA_NEGATIVE = 1 << 2 -SIGNS_BOB_COLLATERAL_DELTA_NEGATIVE = 1 << 3 - -FLAGS_SIGNER_IS_BOB = 1 << 0 - -NOBODY = b'\x00' * 64 -NOSIG = b'\x00' * 65 -PFX_LEDGER_HEAD = b'\x01' -PFX_LEDGER_ENTRY = b'\x02' -PFX_LEDGER_COUNTERKEY = b'\x03' - - -def padbytes(b, padsize=4096): - l = padsize - (len(b) % padsize) - b += os.urandom(l) - return b - -h = hashlib.new('sha256') -h.update(b'1234') -z = h.digest() - -def alice(w): - k = ECC.generate(curve='Ed25519') - pk_pkcs8 = k.export_key(format='DER') - pk_der = Crypto.IO.PKCS8.unwrap(pk_pkcs8) - pk = Crypto.Util.asn1.DerOctetString().decode(pk_der[1], strict=True).payload - pubk = k.public_key().export_key(format='raw') - - wt = io.BytesIO() - wt.write(b"(8:key-data(10:public-key(3:ecc(5:curve7:Ed25519)(1:q32:") - wt.write(pubk) - wt.write(b")))(11:private-key(3:ecc(5:curve7:Ed25519)(1:q32:") - wt.write(pubk) - wt.write(b")(1:d32:") - wt.write(pk) - wt.write(b"))))") - b = wt.getvalue() - l = len(b) - bl = l.to_bytes(4, byteorder='little') - - nonce = os.urandom(12) - cph = ChaCha20_Poly1305.new(key=z, nonce=nonce) - r = cph.encrypt(bl + b) - r = padbytes(r) - w.write(nonce + r) - - return pubk - - -def bob(d): - k = ECC.generate(curve='Ed25519') - pubk = k.public_key().export_key(format='raw') - - - wt = io.BytesIO() - wt.write(b"(8:key-data(10:public-key(3:ecc(5:curve7:Ed25519)(1:q32:") - wt.write(pubk) - wt.write(b"))))") - b = wt.getvalue() - - env = lmdb.open(d) - dbi = env.open_db() - - k = PFX_LEDGER_COUNTERKEY = b'\x03' - - with env.begin(write=True) as tx: - tx.put(k + pubk, b'bob') - - return pubk - - -def db_init(d): - d = os.path.join(d, 'testdata_mdb') - logg.info('using d for db' + d) - - try: - shutil.rmtree(d) - except FileNotFoundError: - pass - os.makedirs(d) - return d - - -def to_absflag(v): - flag = False - if v < 0: - flag = True - return (abs(v), flag,) - - -class LedgerContent(email.message.EmailMessage): - - def __init__(self): - super(LedgerContent, self).__init__() - self.set_default_type("text/plain") - self.add_header("Subject", fake.sentence()) - self.set_content(fake.paragraph()) - - - def kv(self): - b = self.as_bytes() - h = hashlib.new("sha512") - h.update(b) - z = h.digest() - return (z, b,) - - -class LedgerHeadContent(LedgerContent): - pass - - -class LedgerEntryContent(LedgerContent): - pass - - -class LedgerHead: - - def __init__(self, alice_key=None, bob_key=None, body=NOBODY): - self.uoa = "USD" - self.uoa_decimals = 2 - if alice_key == None: - alice_key = os.urandom(65) - self.alice_pubkey_ref = alice_key - if bob_key == None: - bob_key = os.urandom(65) - self.bob_pubkey_ref = bob_key - logg.info('new ledger header with alice {} bob {}'.format(self.alice_pubkey_ref.hex(), self.bob_pubkey_ref.hex())) - self.body = LedgerHeadContent() - - - def __serialize_add(self, b, w): - c = varint.encode(len(b)) - w.write(c) - w.write(b) - - - def __data_add(self, data_dir, k, v): - fp = os.path.join(data_dir, k.hex()) - f = open(fp, 'wb') - #logg.info("fp {}".format(fp)) - f.write(v) - f.close() - - - def serialize(self, data_dir, w=sys.stdout.buffer): - b = self.uoa.encode('utf-8') - self.__serialize_add(b, w) - - b = varint.encode(self.uoa_decimals) - self.__serialize_add(b, w) - - b = self.alice_pubkey_ref - self.__serialize_add(b, w) - - b = self.bob_pubkey_ref - self.__serialize_add(b, w) - - (k, b) = self.body.kv() - self.__data_add(data_dir, k, b) - self.__serialize_add(k, w) - - - @staticmethod - def to_key(b): - r = b'' - r += PFX_LEDGER_HEAD - v = time.time_ns() - b = v.to_bytes(8, byteorder='big') - r += b - - return r - - -class LedgerEntry: - - credit_delta_min = -1000 - credit_delta_max = 1000 - collateral_delta_min = 0 - collateral_delta_max = 0 - - def __init__(self, head, parent=None, body=NOBODY, signer=None): - random.seed(int(time.time_ns())) - self.head = head - self.flags = 0 - self.signs = 0 - self.parent = parent - if self.parent == None: - self.parent = b'\x00' * 64 - self.timestamp = time.time_ns() - - self.body = LedgerEntryContent() - - v = random.randint(self.credit_delta_min, self.credit_delta_max) - self.flags = v % 2 - (v, neg) = to_absflag(v) - self.credit_delta = v - if neg: - if self.flags: - self.signs |= SIGNS_BOB_CREDIT_DELTA_NEGATIVE - else: - self.signs |= SIGNS_ALICE_CREDIT_DELTA_NEGATIVE - - v = random.randint(self.collateral_delta_min, self.collateral_delta_max) - self.response_value = v % 2 - (v, neg) = to_absflag(v) - self.collateral_delta = v - if neg: - if self.flags: - self.signs |= SIGNS_BOB_COLLATERAL_DELTA_NEGATIVE - else: - self.signs |= SIGNS_ALICE_COLLATERAL_DELTA_NEGATIVE - - #self.request_signature = NOSIG - #self.response_signature = NOSIG - self.request_signature = os.urandom(65) - self.response_signature = os.urandom(65) - self.signer = signer - - - def __serialize_add(self, b, w): - c = varint.encode(len(b)) - w.write(c) - w.write(b) - - - def __data_add(self, data_dir, k, v): - fp = os.path.join(data_dir, k.hex()) - f = open(fp, 'wb') - #logg.info("fp {}".format(fp)) - f.write(v) - f.close() - - - def serialize(self, data_dir, w=sys.stdout.buffer): - b = self.flags.to_bytes(1) - self.__serialize_add(b, w) - - b = self.parent - self.__serialize_add(b, w) - - b = self.timestamp.to_bytes(8, byteorder='big') - self.__serialize_add(b, w) - - b = self.signs.to_bytes(1) - self.__serialize_add(b, w) - -# realvalue = self.credit_delta -# if self.flags & FLAGS_SIGNER_IS_BOB: -# if (self.signs & SIGNS_BOB_CREDIT_DELTA_NEGATIVE): -# realvalue *= -1 -# else: -# if (self.signs & SIGNS_ALICE_CREDIT_DELTA_NEGATIVE): -# realvalue *= -1 - - - b = varint.encode(self.credit_delta) - if self.flags: - self.__serialize_add(varint.encode(0), w) - self.__serialize_add(b, w) - if not self.flags: - self.__serialize_add(varint.encode(0), w) - - - #if self.flags: - # self.__serialize_add(b'\x00', w) - #logg.debug('encode flags {} credit {} collateral {}'.format(self.flags, self.credit_delta, self.collateral_delta)) - b = varint.encode(self.collateral_delta) - if not self.flags: - self.__serialize_add(varint.encode(0), w) - self.__serialize_add(b, w) - if not self.flags: - self.__serialize_add(varint.encode(0), w) - - #if self.signer != None: - # self.signature = self.signer(b) - - (k, b) = self.body.kv() - self.__data_add(data_dir, k, b) - self.__serialize_add(k, w) - - self.__serialize_add(self.request_signature, w) - - b = self.response_value.to_bytes(1) - self.__serialize_add(b, w) - - self.__serialize_add(self.response_signature, w) - - return b - - - @staticmethod - def to_key(v, k): - r = b'' - r += PFX_LEDGER_ENTRY - r += k - ts = v[68:68+8] - #logg.debug('ts {}: of {}'.format(ts.hex(), v.hex())) - r += ts - return r - - -def generate_entry(data_dir, head, parent): - o = LedgerEntry(head, parent=parent) - w = io.BytesIO() - r = o.serialize(data_dir, w=w) - h = hashlib.new('sha512') - b = w.getvalue() - h.update(b) - z = h.digest() - return (z, b,) - - -def generate_ledger(data_dir, entry_count=3, alice=None, bob=None): - r = [] - o = LedgerHead(alice_key=alice, bob_key=bob) - w = io.BytesIO() - o.serialize(data_dir, w=w) - h = hashlib.new('sha512') - b = w.getvalue() - h.update(b) - z = h.digest() - r.append((z, b,)) - - k = z - parent = None - for i in range(entry_count): - v = generate_entry(data_dir, k, parent=parent) - # \todo generate key value already here - parent = v[0] - r.append(v) - - return r - - -if __name__ == '__main__': - d = os.path.dirname(__file__) - data_dir = os.path.join(d, 'testdata_resource') - try: - shutil.rmtree(data_dir) - except FileNotFoundError: - pass - os.makedirs(data_dir) - - d = db_init(d) - - f = open('key.bin', 'wb') - alice = alice(f) - f.close() - bob = bob(d) - - print("bo {}\nalice {}\n".format(alice.hex(), bob.hex())) - - env = lmdb.open(d) - dbi = env.open_db() - - count_ledgers = os.environ.get('COUNT', '1') - - with env.begin(write=True) as tx: - for i in range(int(count_ledgers)): - c = random.randint(1, 20) - r = generate_ledger(data_dir, entry_count=c, alice=alice, bob=bob) - - v = r.pop(0) - - z = v[0] - k = LedgerHead.to_key(v[0]) - tx.put(k, v[1]) - - for v in r: - k = LedgerEntry.to_key(v[1], z) - tx.put(k, v[1])