commit 991e6e303c289f9447fd0ce796a341edda18797b
parent 27b3f29a888d9d00aab1bd651483b099d720d2e5
Author: nolash <dev@holbrook.no>
Date: Fri, 24 Sep 2021 05:40:10 +0200
Add missing files
Diffstat:
5 files changed, 231 insertions(+), 0 deletions(-)
diff --git a/pylibswarm/arg.py b/pylibswarm/arg.py
@@ -0,0 +1,18 @@
+# standard imports
+import select
+import sys
+
+
+def stdin_arg():
+ """Retreive input arguments from stdin if they exist.
+
+ Method does not block, and expects arguments to be ready on stdin before being called.
+
+ :rtype: str
+ :returns: Input arguments string
+ """
+ h = select.select([sys.stdin.buffer], [], [])
+ if len(h[0]) > 0:
+ v = h[0][0].read()
+ return v
+ return None
diff --git a/pylibswarm/io.py b/pylibswarm/io.py
@@ -0,0 +1,29 @@
+# standard imports
+import os
+import logging
+
+logg = logging.getLogger(__name__)
+
+
+class Outputter:
+
+ def __init__(self, outdir, prepend_hash=False):
+ self.outdir = outdir
+ self.prepend_hash = prepend_hash
+ os.makedirs(self.outdir, exist_ok=True)
+ logg.info('outputter set to {}'.format(self.outdir))
+
+
+ def dump(self, hsh, data):
+ hsh_hex = hsh.hex()
+ fp = os.path.join(self.outdir, hsh_hex)
+ f = open(fp, 'wb')
+
+ l = len(data)
+ if self.prepend_hash:
+ l += len(hsh)
+ f.write(hsh)
+ f.write(data)
+ f.close()
+
+ logg.debug('wrote {} bytes for chunk file {}'.format(l, hsh_hex))
diff --git a/pylibswarm/runnable/soc.py b/pylibswarm/runnable/soc.py
@@ -0,0 +1,176 @@
+# standard imports
+import argparse
+import sys
+import logging
+import os
+
+# external imports
+from hexathon import (
+ pad as hex_pad,
+ strip_0x,
+ )
+
+# local imports
+from pylibswarm.soc import from_str as soc_meta_from_str
+from pylibswarm.sign import DefaultSigner
+from pylibswarm.arg import stdin_arg
+from pylibswarm.io import Outputter
+
+
+logging.basicConfig(level=logging.WARNING)
+logg = logging.getLogger()
+
+argparser = argparse.ArgumentParser()
+argparser.add_argument('-n', action='store_true', help='skip newline at end of output. (stdout output only)')
+argparser.add_argument('-b', action='store_true', help='output raw bytes.')
+argparser.add_argument('-v', action='store_true', help='verbose output')
+argparser.add_argument('-vv', action='store_true', help='very verbose output')
+argparser.add_argument('-y', type=str, help='key provider (path to keyfile)')
+argparser.add_argument('-o', type=str, help='chunk output location')
+argparser.add_argument('-f', type=str, help='data input location')
+argparser.add_argument('-l', dest='data_length', type=int, help='length of data represented by preimage')
+argparser.add_argument('-u', action='store_true', help='treat input as utf-8 string')
+argparser.add_argument('--topic-string', dest='topic_string', type=str, help='string to use as soc topic.')
+argparser.add_argument('-t', '--topic', type=str, help='hex value to use as soc topic. overrides --topic-string.')
+argparser.add_argument('--index-string', dest='index_string', type=str, help='string to use as soc index.')
+argparser.add_argument('-i', '--index', type=str, help='hex value to use as soc index. overrides --index-string.')
+argparser.add_argument('--id', action='store_true', help='output identifier only')
+argparser.add_argument('--prepend-hash', dest='prepend_hash', action='store_true', help='prepend hash bytes to chunk output (no effect without -o)')
+argparser.add_argument('data', nargs='?', type=str, help='data to embed in soc.')
+largs = argparser.parse_args(sys.argv[1:])
+
+
+if largs.vv:
+ logg.setLevel(logging.DEBUG)
+elif largs.v:
+ logg.setLevel(logging.INFO)
+
+filepath = None
+input_data = None
+if largs.f:
+ filepath = os.path.realpath(largs.f)
+ f = open(filepath, 'rb')
+ data = f.read()
+ f.close()
+ logg.info('data read from file: {}'.format(filepath))
+else:
+ data = largs.data
+ if data == None:
+ data = stdin_arg()
+ logg.info('data read from positional argument'.format(filepath))
+ else:
+ logg.info('data read from stdin'.format(filepath))
+
+
+input_data = data
+if not largs.u:
+ input_data.rstrip()
+ if isinstance(input_data, str):
+ input_data = data.encode('utf-8')
+
+input_data_length = len(input_data)
+data_length = input_data_length
+if largs.data_length != None:
+ data_length = largs.data_length
+logg.debug('input length {}'.format(input_data_length))
+logg.debug('span length {}'.format(data_length))
+
+src_topic = None
+src_index = None
+soc_topic = None
+soc_index = None
+
+if largs.topic:
+ src_topic = largs.topic
+ soc_topic = hex_pad(largs.topic, 20)
+elif largs.topic_string:
+ src_topic = largs.topic_string
+ try:
+ soc_topic = soc_meta_from_str(largs.topic_string, 20, 'topic')
+ except ValueError as e:
+ sys.stderr.write(str(e))
+ sys.exit(1)
+logg.debug('topic "{}" parsed as {}'.format(src_topic, soc_topic))
+
+if largs.index:
+ src_index = largs.index
+ soc_index = hex_pad(largs.index, 32)
+elif largs.index_string:
+ src_index = largs.index_string
+ try:
+ soc_index = soc_meta_from_str(largs.index_string, 32, 'index')
+ except ValueError as e:
+ sys.stderr.write(str(e))
+ sys.exit(1)
+logg.debug('index "{}" parsed as {}'.format(src_index, soc_index))
+
+
+if not largs.id:
+ keystore = DefaultSigner()
+ keystore.from_keyfile(largs.y, os.environ.get('WALLET_PASSPHRASE', ''))
+ address = keystore.get_signer_address()
+ logg.info('using keyfile wallet for address {}'.format(address))
+
+
+outputter = None
+if largs.o:
+ outputter = Outputter(largs.o, prepend_hash=largs.prepend_hash)
+
+
+
+def main():
+ soc_topic_bytes = bytes.fromhex(soc_topic)
+ soc_index_bytes = bytes.fromhex(soc_index)
+ out_data = None
+
+ import swarm
+ #soc_identifier_bytes = swarm.soc_identifier(soc_topic_bytes, soc_index_bytes)
+ soc_identifier_bytes = bytes(32)
+ logg.info('generated identifier {}'.format(soc_identifier_bytes.hex()))
+ if largs.id:
+ out_data = soc_identifier_bytes
+ else:
+ soc_sig = None
+ soc_hash = None
+ soc_chunk = None
+ if outputter:
+ (soc_sig, soc_hash, soc_chunk) = swarm.soc_create(
+ soc_identifier_bytes,
+ bytes.fromhex(strip_0x(address)),
+ input_data,
+ input_data_length,
+ data_length,
+ keystore.sign,
+ outputter.dump,
+ )
+ else:
+ (soc_sig, soc_hash, soc_chunk) = swarm.soc_create(
+ soc_identifier_bytes,
+ bytes.fromhex(strip_0x(address)),
+ input_data,
+ input_data_length,
+ data_length,
+ keystore.sign,
+ None,
+ )
+
+ #logg.debug('signature {}'.format(soc_sig.hex()))
+ #logg.debug('hash {}'.format(soc_hash.hex()))
+ #logg.debug('chunk {}'.format(soc_chunk.hex()))
+ logg.debug('signature {}'.format(soc_sig))
+ logg.debug('hash {}'.format(soc_hash))
+ logg.debug('chunk {}'.format(soc_chunk))
+
+ out_data = soc_hash
+
+ if largs.b:
+ sys.stdout.buffer.write(out_data)
+ else:
+ s = '{}'.format(out_data.hex())
+ if not largs.n:
+ s += '\n'
+ sys.stdout.write(s)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/pylibswarm/soc.py b/pylibswarm/soc.py
@@ -0,0 +1,6 @@
+def from_str(s, target_length, label):
+ if len(s) > target_length:
+ raise ValueError('{} value {} exceeded max length {}'.format(label, s, target_length))
+ b = s.encode('utf-8')
+ fmt = '{' + ':<0{}s'.format(target_length * 2) + '}'
+ return fmt.format(b.hex())
diff --git a/requirements.txt b/requirements.txt
@@ -0,0 +1,2 @@
+crypto-dev-signer>=0.4.15rc1,<0.5.0
+chainlib-eth>=0.0.9a14,<0.1.0