Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

libhsmd: Python bindings for libhsmd #4498

Merged
merged 5 commits into from
May 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@ endif
# (method=thread to support xdist)
PYTEST_OPTS := -v -p no:logging $(PYTEST_OPTS)
PYTHONPATH=$(shell pwd)/contrib/pyln-client:$(shell pwd)/contrib/pyln-testing:$(shell pwd)/contrib/pyln-proto/:$(shell pwd)/external/lnprototest:$(shell pwd)/contrib/pyln-spec/bolt1:$(shell pwd)/contrib/pyln-spec/bolt2:$(shell pwd)/contrib/pyln-spec/bolt4:$(shell pwd)/contrib/pyln-spec/bolt7
# Collect generated python files to be excluded from lint checks
PYTHON_GENERATED=

# Options to pass to cppcheck. Mostly used to exclude files that are
# generated with external tools that we don't have control over
CPPCHECK_OPTS=-q --language=c --std=c11 --error-exitcode=1 --suppressions-list=.cppcheck-suppress --inline-suppr

# This is where we add new features as bitcoin adds them.
FEATURES :=
Expand Down Expand Up @@ -320,6 +326,7 @@ include devtools/Makefile
include tools/Makefile
include plugins/Makefile
include tests/plugins/Makefile
include contrib/libhsmd_python/Makefile
ifneq ($(FUZZING),0)
include tests/fuzz/Makefile
endif
Expand Down Expand Up @@ -458,7 +465,7 @@ check-python-flake8:
@# E501 line too long (N > 79 characters)
@# E731 do not assign a lambda expression, use a def
@# W503: line break before binary operator
@flake8 --ignore=E501,E731,W503 ${PYSRC}
@flake8 --ignore=E501,E731,W503 --exclude $(shell echo ${PYTHON_GENERATED} | sed 's/ \+/,/g') ${PYSRC}

check-pytest-pyln-proto:
PATH=$(PYLN_PATH) PYTHONPATH=$(PYTHONPATH) $(PYTEST) contrib/pyln-proto/tests/
Expand All @@ -468,10 +475,10 @@ check-includes: check-src-includes check-hdr-includes

# cppcheck gets confused by list_for_each(head, i, list): thinks i is uninit.
.cppcheck-suppress:
@git ls-files -- "*.c" "*.h" | grep -vE '^ccan/' | xargs grep -n '_for_each' | sed 's/\([^:]*:.*\):.*/uninitvar:\1/' > $@
@git ls-files -- "*.c" "*.h" | grep -vE '^(ccan|contrib)/' | xargs grep -n '_for_each' | sed 's/\([^:]*:.*\):.*/uninitvar:\1/' > $@

check-cppcheck: .cppcheck-suppress
@trap 'rm -f .cppcheck-suppress' 0; git ls-files -- "*.c" "*.h" | grep -vE '^ccan/' | xargs cppcheck -q --language=c --std=c11 --error-exitcode=1 --suppressions-list=.cppcheck-suppress --inline-suppr
@trap 'rm -f .cppcheck-suppress' 0; git ls-files -- "*.c" "*.h" | grep -vE '^ccan/' | xargs cppcheck ${CPPCHECK_OPTS}

check-shellcheck:
@git ls-files -- "*.sh" | xargs shellcheck
Expand All @@ -483,7 +490,7 @@ check-tmpctx:
@if git grep -n 'tal_free[(]tmpctx)' | grep -Ev '^ccan/|/test/|^common/setup.c:|^common/utils.c:'; then echo "Don't free tmpctx!">&2; exit 1; fi

check-discouraged-functions:
@if git grep -E "[^a-z_/](fgets|fputs|gets|scanf|sprintf)\(" -- "*.c" "*.h" ":(exclude)ccan/"; then exit 1; fi
@if git grep -E "[^a-z_/](fgets|fputs|gets|scanf|sprintf)\(" -- "*.c" "*.h" ":(exclude)ccan/" ":(exclude)contrib/"; then exit 1; fi

# Don't access amount_msat and amount_sat members directly without a good reason
# since it risks overflow.
Expand Down
3 changes: 1 addition & 2 deletions common/bolt12.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,7 @@ bool bolt12_check_signature(const struct tlv_field *fields,
const char *messagename,
const char *fieldname,
const struct pubkey32 *key,
const struct bip340sig *sig)
NO_NULL_ARGS;
const struct bip340sig *sig);

/* Given a tal_arr of chains, does it contain this chain? */
bool bolt12_chains_match(const struct bitcoin_blkid *chains,
Expand Down
4 changes: 4 additions & 0 deletions contrib/libhsmd_python/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
dist
build
src
libhsmd.egg-info
1 change: 1 addition & 0 deletions contrib/libhsmd_python/MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
global-exclude src
12 changes: 12 additions & 0 deletions contrib/libhsmd_python/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/make

LIBHSMD_PY_GEN_FILES := contrib/libhsmd_python/swig_wrap.c \
contrib/libhsmd_python/libhsmd.py

PYTHON_GENERATED += contrib/libhsmd_python/libhsmd.py
CPPCHECK_OPTS += --suppress=nullPointer:contrib/libhsmd_python/swig_wrap.c

# Swig by default generates stubs in the file's directory, which is
# what we want.
$(LIBHSMD_PY_GEN_FILES): contrib/libhsmd_python/swig.i $(HSMD_SRC)
swig -python -builtin contrib/libhsmd_python/swig.i
Empty file.
111 changes: 111 additions & 0 deletions contrib/libhsmd_python/libhsmd.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# This file was automatically generated by SWIG (http://www.swig.org).
# Version 3.0.12
#
# Do not make changes to this file unless you know what you are doing--modify
# the SWIG interface file instead.

from sys import version_info as _swig_python_version_info
if _swig_python_version_info >= (2, 7, 0):
def swig_import_helper():
import importlib
pkg = __name__.rpartition('.')[0]
mname = '.'.join((pkg, '_libhsmd')).lstrip('.')
try:
return importlib.import_module(mname)
except ImportError:
return importlib.import_module('_libhsmd')
_libhsmd = swig_import_helper()
del swig_import_helper
elif _swig_python_version_info >= (2, 6, 0):
def swig_import_helper():
from os.path import dirname
import imp
fp = None
try:
fp, pathname, description = imp.find_module('_libhsmd', [dirname(__file__)])
except ImportError:
import _libhsmd
return _libhsmd
try:
_mod = imp.load_module('_libhsmd', fp, pathname, description)
finally:
if fp is not None:
fp.close()
return _mod
_libhsmd = swig_import_helper()
del swig_import_helper
else:
import _libhsmd
# pull in all the attributes from _libhsmd
if __name__.rpartition('.')[0] != '':
if _swig_python_version_info >= (2, 7, 0):
try:
from ._libhsmd import *
except ImportError:
from _libhsmd import *
else:
from _libhsmd import *
else:
from _libhsmd import *
del _swig_python_version_info

try:
_swig_property = property
except NameError:
pass # Python < 2.2 doesn't have 'property'.

try:
import builtins as __builtin__
except ImportError:
import __builtin__

def _swig_setattr_nondynamic(self, class_type, name, value, static=1):
if (name == "thisown"):
return self.this.own(value)
if (name == "this"):
if type(value).__name__ == 'SwigPyObject':
self.__dict__[name] = value
return
method = class_type.__swig_setmethods__.get(name, None)
if method:
return method(self, value)
if (not static):
if _newclass:
object.__setattr__(self, name, value)
else:
self.__dict__[name] = value
else:
raise AttributeError("You cannot add attributes to %s" % self)


def _swig_setattr(self, class_type, name, value):
return _swig_setattr_nondynamic(self, class_type, name, value, 0)


def _swig_getattr(self, class_type, name):
if (name == "thisown"):
return self.this.own()
method = class_type.__swig_getmethods__.get(name, None)
if method:
return method(self)
raise AttributeError("'%s' object has no attribute '%s'" % (class_type.__name__, name))


def _swig_repr(self):
try:
strthis = "proxy of " + self.this.__repr__()
except __builtin__.Exception:
strthis = ""
return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)

try:
_object = object
_newclass = 1
except __builtin__.Exception:
class _object:
pass
_newclass = 0

# This file is compatible with both classic and new-style classes.


74 changes: 74 additions & 0 deletions contrib/libhsmd_python/libhsmd_python.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#include <ccan/str/hex/hex.h>
#include <libhsmd_python.h>

char *init(char *hex_hsm_secret, char *network_name) {
const struct bip32_key_version *key_version;
struct secret sec;
u8 *response;
setup_locale();
if (sodium_init() == -1) {
fprintf(
stderr,
"Could not initialize libsodium. Maybe not enough entropy"
" available ?");
return NULL;
}

wally_init(0);
secp256k1_ctx = wally_get_secp_context();

sodium_mlock(&sec, sizeof(sec));
if (!hex_decode(hex_hsm_secret, strlen(hex_hsm_secret), sec.data,
sizeof(sec.data))) {
fprintf(stderr,
"Expected hex_hsm_secret of length 64, got %zu\n",
strlen(hex_hsm_secret));
return NULL;
}

/* Look up chainparams by their name */
chainparams = chainparams_for_network(network_name);
if (chainparams == NULL) {
fprintf(stderr, "Could not find chainparams for network %s\n",
network_name);
return NULL;
}

key_version = &chainparams->bip32_key_version;

response = hsmd_init(sec, *key_version);
sodium_munlock(&sec, sizeof(sec));

char *res = tal_hex(NULL, response);
tal_free(response);
return res;
}

char *handle(long long cap, long long dbid, char *peer_id, char *hexmsg) {
const tal_t *ctx = tal_arr(NULL, u8, 0);
size_t res_len;
u8 *response, *request = tal_hexdata(ctx, hexmsg, strlen(hexmsg));
char *res;
struct hsmd_client *client;
struct node_id *peer = NULL;
printf("%llu: %s\n", cap, hexmsg);
if (peer_id != NULL) {
peer = tal(ctx, struct node_id);
node_id_from_hexstr(hexmsg, strlen(hexmsg), peer);
client = hsmd_client_new_peer(ctx, cap, dbid, peer, NULL);
} else {
client = hsmd_client_new_main(ctx, cap, NULL);
}
response = hsmd_handle_client_message(NULL, client, request);
printf("%s\n", tal_hex(ctx, response));
if (response == NULL)
return tal_free(ctx);

res = tal_hex(NULL, response);
res_len = hex_str_size(tal_bytelen(response));
res = malloc(res_len);
hex_encode(response, tal_bytelen(response), res, res_len);

tal_free(ctx);
return res;
}
8 changes: 8 additions & 0 deletions contrib/libhsmd_python/libhsmd_python.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef LIGHTNING_CONTRIB_LIBHSMD_PYTHON_LIBHSMD_PYTHON_H
#define LIGHTNING_CONTRIB_LIBHSMD_PYTHON_LIBHSMD_PYTHON_H

#include <hsmd/libhsmd.h>
char *handle(long long cap, long long dbid, char *peer_id, char *msg);
char *init(char *hex_hsm_secret, char *network_name);

#endif /* LIGHTNING_CONTRIB_LIBHSMD_PYTHON_LIBHSMD_PYTHON_H */
Loading