[PATCH] gnu: Add c-lightning.

  • Open
  • quality assurance status badge
Details
2 participants
  • ZmnSCPxj
  • Léo Le Bouter
Owner
unassigned
Submitted by
ZmnSCPxj
Severity
normal
Z
Z
ZmnSCPxj wrote on 16 Mar 2021 09:40
(name . guix-patches@gnu.org)(address . guix-patches@gnu.org)
pIzl3qY1MjcwPK5NRfKDs3jl1Gf8zurLPn-2e60bUbwzJgLjgoqtJZ82_CMCCRoIyinyASxSXrIxa4yXMW9VfDCfl8P0Gs2_6_J3Iz0r2Go=@protonmail.com
Good morning Guix developers,

C-Lightning is one of the earliest living implementations of the Lightning
Network protocol.
I am one of the developers of this implementation.

I tested this as follows:

* Extracted the package `c-lightning` into a `c-lightning.scm` file.
* Ran `guix build --rounds=4 -f c-lightning.scm` on an X86-64 server to
check for reproducability issues.
* Ran the compiled `lightningd` with `lightningd --version`,
`lightningd --help`, and the developer-secret undocumented
`lightningd --test-daemons-only` and checked they work correctly.
* Ran the compiled `lightningd` with `lightningd --proxy=127.0.0.1:9050
--bind-addr=127.0.0.1:9735 --addr=statictor:127.0.0.1:9051
--always-use-proxy=true` on a server with Bitcoin and Tor installed,
and checked that it indeed created an LN wallet and started operating
the node.
* This also tests the SQLITE database backend and that the sub-daemons
are accessible and runnable.
* From an existing Lightning Network node, did a `lightning-cli connect`
to the new node running on the above command, and confirmed that the
above new node was connected to, and that it started downloading the
gossip map (the first thing every new node does when it initially gets
connected to the network).
* On a separate X86-64 machine with the same Guix commit version, copied
the `c-lightning.scm` file and reran `guix build --rounds=4 -f
c-lightning.scm` as well.
* Checked that the same `/gnu/store` path was produced on the separate
machine as on the first test server.
* Checked that this command produced the exact same text on both computers:
`find ${GNU_STORE_PATH} -type f | sort | xargs -n1 sha256sum`.
* Extracted the package `c-lightning-postgresql` into a
`c-lightning-postgresql.scm` file.
* Ran `guix build --rounds=4 -f c-lightning-postgresql.scm` on a X86-64
server to check for reproducibility issues.
* Chekced that `strings ${GNU_STORE_PATH}/bin/lightningd` for the
`c-lightning-postgresql` had references to `PQ*` functions, and that
the `c-lightning` version had none, meaning that `c-lightning-postgresql`
indeed included PostgreSQL support.

Thus, PostgreSQL support is not fully tested yet, but I believe the
produced binaries will work correctly as a C-Lightning instance.
Therefore I would like to submit this patch for inclusion into Guix.

Some notes:

* C-Lightning includes an extensive suite of tests, but these require
several additional python packages, some of which (e.g.
`python-bitcoinlib`) are not yet in Guix.
The tests are extensive and *very long*, running the entire test
suite can take an hour or more depending on exact settings.
* I took advantage of the functional nature of Guix and disabled the
relative-path `BINTOPKGLIBEXECDIR`, making it an absolute path, as
it also incidentally solves the issue of "upgrading C-lightning may
cause strange problems in a running instance".
See patch for more details.
* Our `configure` and `Makefile` are weird and I should probably go
fix those upstream.

Regards,
ZmnSCPxj

From 490aa608765228fbb6bb64b9fa679bb4c8145001 Mon Sep 17 00:00:00 2001
From: ZmnSCPxj jxPCSnmZ <ZmnSCPxj@protonmail.com>
Date: Mon, 15 Mar 2021 11:53:35 +0000
Subject: [PATCH] gnu: Add c-lightning.

* gnu/packages/finance.scm (c-lightning, c-lightning-postgresql): New variables.
---
gnu/packages/finance.scm | 153 +++++++++++++++++++++++++++++++++++++++
1 file changed, 153 insertions(+)

Toggle diff (181 lines)
diff --git a/gnu/packages/finance.scm b/gnu/packages/finance.scm
index e6df40c168..4b565ddfeb 100644
--- a/gnu/packages/finance.scm
+++ b/gnu/packages/finance.scm
@@ -22,6 +22,7 @@
;;; Copyright © 2020 Vinicius Monego <monego@posteo.net>
;;; Copyright © 2020 Carlo Holl <carloholl@gmail.com>
;;; Copyright © 2020 Giacomo Leidi <goodoldpaul@autistici.org>
+;;; Copyright © 2021 ZmnSCPxj jxPCSnmZ <ZmnSCPxj@protonmail.com>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -57,6 +58,7 @@
#:use-module (gnu packages aidc)
#:use-module (gnu packages autotools)
#:use-module (gnu packages base)
+ #:use-module (gnu packages bash)
#:use-module (gnu packages boost)
#:use-module (gnu packages check)
#:use-module (gnu packages compression)
@@ -99,6 +101,7 @@
#:use-module (gnu packages qt)
#:use-module (gnu packages readline)
#:use-module (gnu packages sphinx)
+ #:use-module (gnu packages sqlite)
#:use-module (gnu packages texinfo)
#:use-module (gnu packages textutils)
#:use-module (gnu packages time)
@@ -1676,3 +1679,152 @@ Interface (UI) for the hledger accounting system. It can be used as a
local, single-user UI, or as a multi-user UI for viewing, adding, and
editing on the Web.")
(license license:gpl3)))
+
+(define-public c-lightning
+ (package
+ (name "c-lightning")
+ (version "0.9.3")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (string-append
+ "https://github.com/ElementsProject/lightning/releases/download/"
+ "v" version "/clightning-v" version ".zip"))
+ (sha256
+ (base32 "1chqzxcqpr49vbayrw4213lznmyw4lcghcdh6afxbk4bxlhkjmml"))))
+ (build-system gnu-build-system)
+ (native-inputs
+ `(("autoconf" ,autoconf)
+ ("automake" ,automake)
+ ("bash" ,bash)
+ ("libtool" ,libtool)
+ ("pkg-config" ,pkg-config)
+ ("python" ,python)
+ ("python-mako" ,python-mako)
+ ("sed" ,sed)
+ ("unzip" ,unzip)
+ ("which" ,which)))
+ (inputs
+ `(("gmp" ,gmp)
+ ("sqlite" ,sqlite)
+ ("zlib" ,zlib)))
+ (arguments
+ ;; Tests exist, but need a lot of Python packages (some not available
+ ;; on Guix) and they are incompatible with our BINTOPKGLIBEXECDIR hack.
+ `(#:tests? #f
+ #:phases
+ (modify-phases %standard-phases
+ (add-before 'configure 'patch-makefile
+ (lambda _
+ (substitute* "Makefile"
+ ;; The C-lightning Makefile uses the PYTHONPATH
+ ;; variable, which causes Guix builds to fail
+ ;; since the environment variable is masked by
+ ;; the Makefile variable.
+ ;; Insert the contents of the variable into the
+ ;; Makefile.
+ (("^PYTHONPATH=")
+ (string-append
+ "PYTHONPATH="
+ (getenv "PYTHONPATH")
+ ":"))
+ ;; C-lightning will spawn a number of other
+ ;; processes from binaries installed in its
+ ;; libexecdir.
+ ;; It normally uses relative paths so that
+ ;; users can move around the installation
+ ;; location.
+ ;; However, it does have the drawback that if
+ ;; the installation location is overwritten
+ ;; with a newer version while an existing
+ ;; instance is still running, any new
+ ;; sub-processes launched will be the new
+ ;; version, which is likely incompatible with
+ ;; the running instance.
+ ;; Since Guix would not allow the store
+ ;; directory to be moved anyway, we use an
+ ;; absolute path instead in the below
+ ;; substitution.
+ ;; With Guix and an absolute path, even if a
+ ;; running instance was launched from a
+ ;; profile and that profile is upgraded to a
+ ;; newer version, the running instance will
+ ;; refer to the absolute store directory
+ ;; containing binaries of the running version.
+ (("BINTOPKGLIBEXECDIR=.*$")
+ "BINTOPKGLIBEXECDIR='\"'\"$(pkglibexecdir)\"'\"'\n"))))
+ ;; C-lightning configure is unusual, it does not understand
+ ;; the standard parameters Guix passes in, so, provide those
+ ;; by env variables.
+ (replace 'configure
+ (lambda* (#:key outputs inputs (configure-flags '())
+ #:allow-other-keys)
+ (let* ((bash (string-append (assoc-ref inputs "bash") "/bin/bash"))
+ (python (assoc-ref inputs "python"))
+ (prefix (assoc-ref outputs "out"))
+ (flags (cons*
+ "CC=gcc"
+ (string-append "--prefix=" prefix)
+ configure-flags)))
+ (setenv "PYTHON" (string-append python "/bin/python3"))
+ (setenv "CONFIG_SHELL" bash)
+ (setenv "SHELL" bash)
+ (format #t "build directory: ~s~%" (getcwd))
+ (format #t "configure flags: ~s~%" flags)
+ (apply invoke bash
+ "./configure"
+ flags))))
+ ;; Rather than call the configure script of its external
+ ;; libraries from its own configure script, the external
+ ;; configure are created and called at build time.
+ ;; Unfortunately, it is a single Makefile stanza which
+ ;; does the autoreconf, configure, and make.
+ ;; This means we cannot "cut" through here by creating
+ ;; the external configure before this step (the Makefile
+ ;; stanza will recreate and overwrite the external
+ ;; configure), we have to modify the autogen.sh scripts
+ ;; of the external libraries instead so that they
+ ;; patch the shebangs after autoreconf.
+ (add-before 'build 'fix-autoreconf
+ (lambda _
+ (substitute* "external/libsodium/autogen.sh"
+ (("exec autoreconf(.*)$" exec-autoreconf flags)
+ (string-append
+ "autoreconf" flags
+ "sed 's:/bin/sh:" (getenv "SHELL") ":g' < configure > configure.tmp\n"
+ "mv configure.tmp configure\n"
+ "chmod +x configure\n"
+ "exit 0\n")))
+ (substitute* "external/libwally-core/tools/autogen.sh"
+ (("autoreconf(.*)$" autoreconf)
+ (string-append
+ autoreconf
+ "sed 's:/bin/sh:" (getenv "SHELL") ":g' < configure > configure.tmp\n"
+ "mv configure.tmp configure\n"
+ "chmod +x configure\n"))))))))
+ (home-page "https://github.com/ElementsProject/lightning")
+ (synopsis "Lightweight Lightning Network protocol implementation in C")
+ (description
+ "c-lightning is a lightweight, highly customizable, and standard
+compliant implementation of the Lightning Network protocol.")
+ (license license:expat)))
+
+(define-public c-lightning-postgresql
+ (package
+ (inherit c-lightning)
+ (name "c-lightning-postgresql")
+ (inputs
+ `(("postgresql" ,postgresql)
+ ;; C-Lightning requires SQLITE3 as of 0.9.3, and will
+ ;; fail to build if it is not found.
+ ;; (The configure script will allow PostgreSQL without
+ ;; SQLITE3 but some build tool of C-Lightning fails if
+ ;; SQLITE3 is not found.)
+ ,@(package-inputs c-lightning)))
+ (description
+ "c-lightning is a lightweight, highly customizable, and standard
+compliant implementation of the Lightning Network protocol.
+
+This package includes support for using a PostgreSQL database to back
+your node; you will need to set up the PostgreSQL separately and pass
+in its details using an appropriate flag setting.")))
--
2.30.1
L
L
Léo Le Bouter wrote on 16 Mar 2021 10:13
81c654076d3c07c0f7d1657b4e44dce29a01eca2.camel@zaclys.net
Hello!

Thanks for the patch!

I built it and it was successful, however, few comments:

The various hacks in the recipe to get a working build seem troublesome
maintenance-wise, is it possible you think since you are a developer
that you make the build scripts a bit more standard in the project?

I see there's some vendored libraries: gheap, jsmn, libbacktrace,
libsodium, libwally-core ; Is it possible to unvendor those and create
separate packages for each of them? Or is there a requirement of strict
behavior here, either way, you could also create separate packages for
each of them even if those are specific to c-lightning. It would make
the main recipe cleaner, since as far as I can see it's also why the
build system is so stubborn to GNU Guix? That it also attempts to build
vendored libraries?

Léo
-----BEGIN PGP SIGNATURE-----

iQIzBAABCgAdFiEEFIvLi9gL+xax3g6RRaix6GvNEKYFAmBQdqMACgkQRaix6GvN
EKa21RAAuoYovFsFSLETZcz/z6l0U8QfH/j5arsEgaftiHdxLpPEZr8tLw5mslJG
PM0dCdDC4YPvjhvgRMJRsiqUPwsdK3dya6cqMvWA/P0A10bM6iPPTFyLR4MIzeW0
DpwmZnJricitJcXfh405kRqfzSUfZIW9/vtueZfIaGhxscxwpogPDrfNMIGeZNFW
stSO7BeLusx6TRt2gKzs+/Yg0EkEwT6FKIAGwBloZEfShZ35nWd7G93kkKLMhQKf
5dqCZDSQcmM7uRvThEOV+R1q0kFHPzUBcR8lV8K0S+/urrJ8XQtCf8JRrLGpApgV
GoaMXJVNivmUBENkk6dnw+cHpPFf7dQ0fcpnjmqPve6blB1RQDEeOe0iK441edZU
AmBm6qmmQVgoRR5C7S2vwil+LMPfmBh3RER0+PhqH+AJ9XqQJhxlVfUYdeAluFFw
9Dq8PhZF8fE+sgnGDpNQFNt+RpCgfZiUw9nzeMko1DJGm5U4jZFIyurpuHupoxtn
EXIV9cGhSTPzkgEKI0dEcT3kt75taCYKJiou7Pu+n6g/B+rnMeIbd/NuciPKSbbQ
ArjdzYnNhgwW/joZ6g5bikBup+h5u3ScmJBzPPveGmaZv4tZ/29lhpKD/X1cER3e
VjvFgA42rIN52oow+hvWALyhgpmu/r8JH0Vd0BwAx9aOvAuDs7U=
=jKNa
-----END PGP SIGNATURE-----


L
L
Léo Le Bouter wrote on 16 Mar 2021 10:17
9436292ea880757cf47a5ce59879e6e7098ff195.camel@zaclys.net
Additionally, please do enable the test suite it's really valuable in
GNU Guix.

I can help packaging the necessary Python dependencies, also we have a
Python importer, e.g. "$ guix import pypi -r <pkg>" to help us go
faster at it.
-----BEGIN PGP SIGNATURE-----

iQIzBAABCgAdFiEEFIvLi9gL+xax3g6RRaix6GvNEKYFAmBQd8YACgkQRaix6GvN
EKYqLBAAmakARL2beMnhQCSKYrZ2cSVIYh72Rld8jCG33gK5mI+kY+NzIRHjhnMi
D60Isyxt3JLtTcvnpGO+qZb+7nvDZRfuxJJM20V8lhPd73RZ85cUJqGs052CtatM
dDoGlIeTN1YMdJe65qiaqLA9HRq8PhShRT5PwAIjnzPi0TslXWSw9XOx5jC1lmn7
33wsDiiY0qq+L71zhL5ho21MQDaMqmIDPUqs+cSJonnPo3kC9S6JIT8O20BzejxV
s0F6A5q6cIRl5MMvPAxbLgnA700j/Qi7FYptb6Qi6Wu538XSFKiEzOjm+PHmTqKq
nlnbdXaaeYxh+ljUFNSRgMLsGz58FQUW4QEV2VsJz/gOk4XGspQOOQ7qIsBjQNH8
sqwgToEBTt45EYtzvQRhp02m9VuW3q36CDdz2KnA0WBmSsCAGMDY8Y34QeE2cgsZ
ZlGY4hzUAu/dqamncoiaYsvnuzxi+uP+73qAjHFqD7FSrBOkbOezoeChsCmFuone
bp3VbJ9KFfz8wHIcBt6GSpO8NRE6WAa4hxCLLUyNGYK113o+oTGm+cM+7Y2ns/N+
xo1bgSPMxC4WSqCqyM8TpYslaSDy3KMVv4OuioR2/WVNg8h5Z1kxgkYOxuzBNd5I
kwlsRXjetD+7oLgOMZiKIwCsyatnGW6l4w0eQdhU10/ZMZxMHg4=
=byf2
-----END PGP SIGNATURE-----


Z
Z
ZmnSCPxj wrote on 16 Mar 2021 12:27
(name . Léo Le Bouter)(address . lle-bout@zaclys.net)(name . 47187@debbugs.gnu.org)(address . 47187@debbugs.gnu.org)
Pnk0YahvVi3QLAGeLyIGEl3tdFaE1AtAtHOvIRjW1gPAUzzjYF9dC0U8Di_kRe84FfmQw_1hr7sSRE4enMKw0Kzd74mMvR-CGQyhWhZJelw=@protonmail.com
Good morning Leo,

Toggle quote (4 lines)
> The various hacks in the recipe to get a working build seem troublesome
> maintenance-wise, is it possible you think since you are a developer
> that you make the build scripts a bit more standard in the project?

Already working on that, but 0.10.0 will release soon and I doubt my changes will make it by then, so Guix might get c-lightning to 0.10.1 or later if we wait for it.

Toggle quote (9 lines)
> I see there's some vendored libraries: gheap, jsmn, libbacktrace,
> libsodium, libwally-core ; Is it possible to unvendor those and create
> separate packages for each of them? Or is there a requirement of strict
> behavior here, either way, you could also create separate packages for
> each of them even if those are specific to c-lightning. It would make
> the main recipe cleaner, since as far as I can see it's also why the
> build system is so stubborn to GNU Guix? That it also attempts to build
> vendored libraries?

I think it is more the custom `configure` script.
The custom `configure` script also compiles a ***C*** program that then generates the configuration for the `ccan` library of the project, meaning cross-compilation requires special work for C-Lightning.
And `configure` does not call `configure` of the included libraries as well.

Yes, it is true that there is something of a requirement of a strict behavior here, I suppose it is possible to use `git-fetch` instead of `url-fetch` for our external libraries.
How do I generate `guix hash` for `git-fetch`ed `source`s?
However it also means that every release of C-Lightning I have to go double-check what git commit to use for each library (though `jsmn` and `libbacktrace` at least seem very stable).

But it looks to me that unvendoring will require more extensive patching of the `Makefile` and an even larger maintenance burden on Guix side?

`libwally-core` itself depends on another library `libsecp256k1`, so I suppose it must transitively be unvendored as well.

Toggle quote (3 lines)
> Additionally, please do enable the test suite it's really valuable in
> GNU Guix.

The test suite is fairly large and can take a significant amount of time to run in full.

In addition, part of the test includes checks which take advantage of `BINTOPKGLIBEXECDIR` relative path we normally use, which I want to disable for Guix at least since the relative path only has an advantage if the user wants to move the installation after-the-fact to a different location (and on Guix the "installation" path cannot be moved anyway).
Using an absolute `BINTOPKGLIBEXECDIR` gives an advantage as mentioned in the comments that a profile being upgraded from one version of C-Lightning to another does not cause problems for daemons currently running off the profile.
The test can be disabled (but not easily), I suppose.

Toggle quote (4 lines)
> I can help packaging the necessary Python dependencies, also we have a
> Python importer, e.g. "$ guix import pypi -r <pkg>" to help us go
> faster at it.

Please do, I am not very familiar with any Python infrastructure and am primarily a C programmer here, I just barely hack together some kind of test in Python.


Regards,
ZmnSCPxj
L
L
Léo Le Bouter wrote on 16 Mar 2021 13:46
(name . ZmnSCPxj)(address . ZmnSCPxj@protonmail.com)(name . 47187@debbugs.gnu.org)(address . 47187@debbugs.gnu.org)
8f7d4c04d96fdf8cf1239c476c4c869f92446ada.camel@zaclys.net
On Tue, 2021-03-16 at 11:27 +0000, ZmnSCPxj wrote:
Toggle quote (4 lines)
> Already working on that, but 0.10.0 will release soon and I doubt my
> changes will make it by then, so Guix might get c-lightning to 0.10.1
> or later if we wait for it.

Awesome!

Toggle quote (4 lines)
> Yes, it is true that there is something of a requirement of a strict
> behavior here, I suppose it is possible to use `git-fetch` instead of
> `url-fetch` for our external libraries.

Yes you can use git-fetch, to make sure we are on the same page, are
you speaking of strict behavior requirements like for Bitcoin Core's
consensus code?

Toggle quote (2 lines)
> How do I generate `guix hash` for `git-fetch`ed `source`s?

Actually what I do is put a wrong hash in and then copy the "actual
hash" from the error. I havent found another way but this definitely
feels subpar and prevents much verification before putting in the hash,
better suggestions welcome.

Toggle quote (8 lines)
> However it also means that every release of C-Lightning I have to go
> double-check what git commit to use for each library (though `jsmn`
> and `libbacktrace` at least seem very stable).
>
> But it looks to me that unvendoring will require more extensive
> patching of the `Makefile` and an even larger maintenance burden on
> Guix side?

Unvendoring is more or less a policy because we must be able to audit
each piece of software separately for freedom issues (licenses,
violations to the GNU FSDG), and it eases work for security-patching
also.

Toggle quote (3 lines)
> `libwally-core` itself depends on another library `libsecp256k1`, so
> I suppose it must transitively be unvendored as well.

Probably, we already have a libsecp256k1 specially for Bitcoin Core.

Toggle quote (3 lines)
> The test suite is fairly large and can take a significant amount of
> time to run in full.

That's fine.

Toggle quote (12 lines)
> In addition, part of the test includes checks which take advantage of
> `BINTOPKGLIBEXECDIR` relative path we normally use, which I want to
> disable for Guix at least since the relative path only has an
> advantage if the user wants to move the installation after-the-fact
> to a different location (and on Guix the "installation" path cannot
> be moved anyway).
> Using an absolute `BINTOPKGLIBEXECDIR` gives an advantage as
> mentioned in the comments that a profile being upgraded from one
> version of C-Lightning to another does not cause problems for daemons
> currently running off the profile.
> The test can be disabled (but not easily), I suppose.

Problematic or unrealistically expensive tests can be disabled yes.

Toggle quote (4 lines)
> Please do, I am not very familiar with any Python infrastructure and
> am primarily a C programmer here, I just barely hack together some
> kind of test in Python.

If you can list the Python dependencies and their version I can look at
packaging them.

Toggle quote (3 lines)
> Regards,
> ZmnSCPxj

Léo
-----BEGIN PGP SIGNATURE-----

iQIzBAABCgAdFiEEFIvLi9gL+xax3g6RRaix6GvNEKYFAmBQqJ4ACgkQRaix6GvN
EKYMUA//ZJUL8DkBhtuS7WPYCcbnViobj2/R8xmSNa006kXkpG8pzlOrhwwTgeHi
Be0oCbLoDefssky0YAZVYOZjBfFb4QyX7S7f9oEBRTmGlPWTxcyNqs+STt/TYJEw
Uqj/tcdpDfEekADnaggyaOkTaiGpHrHfrgcILmIqTRJe9k9LiCX83O9IELr1nXzp
XrKFdMD/9rShKVobqMKtPzdrO5+H7EquC0az3iI/WXvmc/I0qJsS/WdJC62dneHu
kbrwAQvSd6MxJmO/d01MG+zP1k9nZ0eKrQZH4vJz2aznqe7gaDP5buoK0ZO1t15b
XHpsaHqL+TEsOTuj52eBdO0a7g7c1XHkq8DRFLcUz6EapijkGKIIfqavo8m80Lzx
4VZ0WGX//cmAX4ApvzwIUp5j9MRGf6aCZ5Dur5mJY4+j10sWYL2UfX6DoYjX1LBx
3h5DBAIMh9jWrWFUbtOlTIx1oDCoXuma5nUhfA/yPH98nHxYN1sckWkNhu2Z74nW
/wOk+pGfozU6JwgFhSpWDU3xvipP+j+F7l8Ap4RBQtjZtIVfPziv3ETq86raiK6+
w8UDXhDCN5OQhgXNZpZ4kioRxN2CNZUl5DopAVHoaDUiIN1KL4QfGAYjQ8g8Ytsx
PUKxcY66j7Js57N1P3+HRq75s/vNbHFpLwdLxNDvUnRrCrNyDok=
=Egcs
-----END PGP SIGNATURE-----


Z
Z
ZmnSCPxj wrote on 17 Mar 2021 04:42
(name . Léo Le Bouter)(address . lle-bout@zaclys.net)(name . 47187@debbugs.gnu.org)(address . 47187@debbugs.gnu.org)
X0AJfvGmJvZOXkqcxiL1wDpQGbPYwaMG5V24ltJiXsvMhc8i8OZkWd_uAf18tMpgcSq1izVJTiurVFRaflG2_dOtTi7UzrOZwT9DcV0gFo0=@protonmail.com
Good morning Leo,

Toggle quote (8 lines)
> > Yes, it is true that there is something of a requirement of a strict
> > behavior here, I suppose it is possible to use `git-fetch` instead of
> > `url-fetch` for our external libraries.
>
> Yes you can use git-fetch, to make sure we are on the same page, are
> you speaking of strict behavior requirements like for Bitcoin Core's
> consensus code?

Well we need to produce signatures and transactions that pass Bitcoin Core signature validation at least, so it is best to use a version of `libsecp256k1` (which produces signatures) that we know works, as well as `libwally-core` (which produces transactions).
I would personally use the `libsecp256k1` version that `libwally-core` vendors in as well, since there may be specific interactions between `libwally-core` and `libsecp256k1` that may be different if we use the Bitcoin Core version of `libsecp256k1`.

For `libsodium`, at least the hashing has to work correctly, but I think it is simple enough that strict behavior requirements are not so onerous.
Indeed, we usually get this from the OS (but we need a later feature than that available on some old Ubuntu versions, which is why it got vendored in), so I should probably "just" add it as an input.

Toggle quote (8 lines)
>
> > How do I generate `guix hash` for `git-fetch`ed `source`s?
>
> Actually what I do is put a wrong hash in and then copy the "actual
> hash" from the error. I havent found another way but this definitely
> feels subpar and prevents much verification before putting in the hash,
> better suggestions welcome.

Haha I shall do so as well.

Toggle quote (13 lines)
>
> > However it also means that every release of C-Lightning I have to go
> > double-check what git commit to use for each library (though `jsmn`
> > and `libbacktrace` at least seem very stable).
> > But it looks to me that unvendoring will require more extensive
> > patching of the `Makefile` and an even larger maintenance burden on
> > Guix side?
>
> Unvendoring is more or less a policy because we must be able to audit
> each piece of software separately for freedom issues (licenses,
> violations to the GNU FSDG), and it eases work for security-patching
> also.

I understand.

This will require a largish amount of work I think.

Would this technique be acceptable?

* `add-before 'configure 'unvendor-externals`
* `rm -rf` the vendored externals.
* `ln -s` the needed `.h` and `.la`/`.a`/`.so` files from the `inputs` to the expected paths within the `external/` directory.

?

Toggle quote (7 lines)
> > Please do, I am not very familiar with any Python infrastructure and
> > am primarily a C programmer here, I just barely hack together some
> > kind of test in Python.
>
> If you can list the Python dependencies and their version I can look at
> packaging them.

We have a `requirements.txt` file which contains this, I duplicate below:

```
# Dependencies required to build and test c-lightning
mrkd ~= 0.1.6
Mako ~= 1.1.3

# Dependencies from pyln-client
Sphinx ~= 3.4.0
flake8==3.7.8
recommonmark>=0.7.*
sphinx-rtd-theme==0.4.2
sphinxcontrib-websupport==1.1.0
tqdm==4.32.2

# Dependencies from pyln-testing
Flask==1.1.*
cheroot==8.5.*
ephemeral-port-reserve==1.1.1
filelock==3.0.*
flaky ~= 3.7.0
psutil==5.7.*
psycopg2-binary==2.8.*
pytest-rerunfailures==9.1.1
pytest-timeout ~= 1.4.2
pytest-xdist ~= 2.2.0
pytest==6.1.*
python-bitcoinlib==0.11.*

# Dependencies from pyln-proto
base58 ~= 2.0.1
bitstring ~= 3.1.6
coincurve ~= 13.0.0
cryptography ~= 3.2
mypy ~= 0.790
pysocks ~= 1.7.1

# Dependencies from pyln-spec
# None
```

Incidentally, we also install some Python modules.
How do I "properly" export the Python modules within Guix?

Regards,
ZmnSCPxj
L
L
Léo Le Bouter wrote on 18 Mar 2021 07:33
(name . ZmnSCPxj)(address . ZmnSCPxj@protonmail.com)(name . 47187@debbugs.gnu.org)(address . 47187@debbugs.gnu.org)
d144260cff4e907bd263b4f4dbb1a3022ec94ef5.camel@zaclys.net
On Wed, 2021-03-17 at 03:42 +0000, ZmnSCPxj wrote:
Toggle quote (13 lines)
> I understand.
>
> This will require a largish amount of work I think.
>
> Would this technique be acceptable?
>
> * `add-before 'configure 'unvendor-externals`
> * `rm -rf` the vendored externals.
> * `ln -s` the needed `.h` and `.la`/`.a`/`.so` files from the
> `inputs` to the expected paths within the `external/` directory.
>
> ?

Maybe simply add an option like --with-system-libbacktrace etc. in the
build system? And yes remove externals, I think that you should use a
snippet in the origin field instead of a phase for that.

Toggle quote (49 lines)
>
> We have a `requirements.txt` file which contains this, I duplicate
> below:
>
> ```
> # Dependencies required to build and test c-lightning
> https://github.com/ElementsProject/libwally-core/releases/download/release_0.8.0/wallycore-0.8.0-cp36-cp36m-linux_x86_64.whl; 'linux' in sys_platform and python_version ==
> '3.6'
> https://github.com/ElementsProject/libwally-core/releases/download/release_0.8.0/wallycore-0.8.0-cp37-cp37m-linux_x86_64.whl; 'linux' in sys_platform and python_version ==
> '3.7'
> https://github.com/ElementsProject/libwally-core/releases/download/release_0.8.0/wallycore-0.8.0-cp37-cp37m-macosx_10_14_x86_64.whl; sys_platform == 'darwin' and python_version ==
> '3.7'
> mrkd ~= 0.1.6
> Mako ~= 1.1.3
>
> # Dependencies from pyln-client
> Sphinx ~= 3.4.0
> flake8==3.7.8
> recommonmark>=0.7.*
> sphinx-rtd-theme==0.4.2
> sphinxcontrib-websupport==1.1.0
> tqdm==4.32.2
>
> # Dependencies from pyln-testing
> Flask==1.1.*
> cheroot==8.5.*
> ephemeral-port-reserve==1.1.1
> filelock==3.0.*
> flaky ~= 3.7.0
> psutil==5.7.*
> psycopg2-binary==2.8.*
> pytest-rerunfailures==9.1.1
> pytest-timeout ~= 1.4.2
> pytest-xdist ~= 2.2.0
> pytest==6.1.*
> python-bitcoinlib==0.11.*
>
> # Dependencies from pyln-proto
> base58 ~= 2.0.1
> bitstring ~= 3.1.6
> coincurve ~= 13.0.0
> cryptography ~= 3.2
> mypy ~= 0.790
> pysocks ~= 1.7.1
>
> # Dependencies from pyln-spec
> # None
> ```

Thank you, I am going to go through them.

Toggle quote (3 lines)
> Incidentally, we also install some Python modules.
> How do I "properly" export the Python modules within Guix?

I will ask someone else here but you might have to mix the python-
build-system in.

Léo
-----BEGIN PGP SIGNATURE-----

iQIzBAABCgAdFiEEFIvLi9gL+xax3g6RRaix6GvNEKYFAmBS9CAACgkQRaix6GvN
EKY1Lw/8DksDMQmSXp/4ghYlB5LZDaAwIvIEebtMVVve7ULQFgHoJKhRtFpj4Bes
25rKXL6MCXpFGxwsR0++z0ItPR2WCzq0Y8LIUEBufWIv8H1JAr8K/LrqBS6J4TO9
FuvXz0rdqbuUM3JFUBLsHkI9DfNSMlh62Pq5Z891G/SIClPeXR1WTr43CHTSz3hG
j5vB88n4CF4Jco5TrM6RBxgJg+djVx79+k4W35xrqNNlb2xY1umscXrsc6C6VVBz
6GkELEsEyCosIUCFQu42KkLG7gLctxOL7LN+VmWYinsyYOtYSGzBp+jX5TZ14ap9
eA1VDbVCW9fIn0YZoUnLg3PXXPfeqJxmNC6d6T7U1eOM+ISQ7DtH1S/6SOoeCgm6
NDE7iQNsqm3AMlnRC59fRIfb0XCWlRTnxB3d8Qj7IOSQr5SYP/bMwiiPl1YwCerI
lAF6gRqGa9EeYm8oLbkPZV8qNpu93OytmsUwgkeLBx15xGPr3Fvwk0xtDTBZvDGV
NuA48flNy3dGZapGser4RNwfSbXwccGNnVm4HdZJ8fq36QszpxgJv++CxigXo7Jg
zOz62S4E5pz4z68FO1P6cfvNolLgXKe4lFSb8f6DK60XMF9C3gQtS8O9Mc9ScEe+
Z3D4vKhXEqq1uVXdIDo7PALwrl5MLnsdbp4jjo38MVnhoAl2xFQ=
=SuGc
-----END PGP SIGNATURE-----


Z
Z
ZmnSCPxj wrote on 18 Mar 2021 17:54
(name . Léo Le Bouter)(address . lle-bout@zaclys.net)(name . 47187@debbugs.gnu.org)(address . 47187@debbugs.gnu.org)
wrjSkdSBHOIrwL93q4L8NF9bCc-vUcdRbwzfA-5JOSqnmQXoQeCNgZfVpboTv9weMt6QJOZTtrlxz_oEL_JSYNb8PH7VFagAf9xEtExkbrw=@protonmail.com
Good morning Leo,

Toggle quote (17 lines)
> On Wed, 2021-03-17 at 03:42 +0000, ZmnSCPxj wrote:
>
> > I understand.
> > This will require a largish amount of work I think.
> > Would this technique be acceptable?
> >
> > - `add-before 'configure 'unvendor-externals`
> > - `rm -rf` the vendored externals.
> > - `ln -s` the needed `.h` and `.la`/`.a`/`.so` files from the
> > `inputs` to the expected paths within the `external/` directory.
> >
> >
> > ?
>
> Maybe simply add an option like --with-system-libbacktrace etc. in the
> build system?

That would not be simple I think, but let me see what can be done.
For one, it would be fairly difficult to test it outside of a patched Guix, as the packages are not usually available in most distros (which is why we ship the source build with them); e.g. we do not know how to actually find the "system" libbacktrace as no existing system I know of actually ships the libbacktrace we use (Debian ships a libbacktrace for android development, and is not the same package as what we use).
Of the external packages we use, only libsodium is available on Debian (and older Debian/Ubuntu, as mentioned, have an older version that does not have a functionality we require, which is why it is included in our source build as well), so that is the only external we have that we can plausibly say "we can use the system version", because all the others are not available on most systems.

Also --- we would be somewhat wary of taking the "system" `libsecp256k1`, as this is very consensus-critical, and we know that our program works with a very specific version, but cannot assure this to be true if the "system" `libsecp256k1` is not the exact version.
(Note that we cannot take the `libsecp256k1` from `bitcoin-core` because (1) the `bitcoin-core` package uses a vendored `libsecp256k1`, the separate Guix `libsecp256k1` is actually only used by `electrum` and related projects and (2) the interface `bitcoin-core` uses may be different from the interface we use, it would require review before we would be able to assure that the interfaces they use are exactly the same; this would be mitigated by running the full test suite as it also tests consensus-criticality.)
Is there an easy way to ensure that any `libsecp256k1` that gets fed into the `c-lightning` build as an `inputs` is of a specific `git` commit?

Toggle quote (3 lines)
> And yes remove externals, I think that you should use a
> snippet in the origin field instead of a phase for that.

Hmm do you mean something like:

(origin
; whatever...
(snippet
'(begin
(delete-file-recursively "external/gheap")
(delete-file-recursively "external/jsmn")
(delete-file-recursively "external/libbacktrace")
(delete-file-recursively "external/libsodium")
(delete-file-recursively "external/libwally-core"))))

?

Toggle quote (6 lines)
> > Incidentally, we also install some Python modules.
> > How do I "properly" export the Python modules within Guix?
>
> I will ask someone else here but you might have to mix the python-
> build-system in.

How do you mix in a build system?
Would `python-pyqt` be a good example of such "mix in"?

Regards,
ZmnSCPxj
L
L
Léo Le Bouter wrote on 19 Mar 2021 10:09
(name . ZmnSCPxj)(address . ZmnSCPxj@protonmail.com)(name . 47187@debbugs.gnu.org)(address . 47187@debbugs.gnu.org)
f4dfb51a937774ec3a4033e14ff74c1a27532caf.camel@zaclys.net
On Thu, 2021-03-18 at 16:54 +0000, ZmnSCPxj wrote:
Toggle quote (15 lines)
> That would not be simple I think, but let me see what can be done.
> For one, it would be fairly difficult to test it outside of a patched
> Guix, as the packages are not usually available in most distros
> (which is why we ship the source build with them); e.g. we do not
> know how to actually find the "system" libbacktrace as no existing
> system I know of actually ships the libbacktrace we use (Debian ships
> a libbacktrace for android development, and is not the same package
> as what we use).
> Of the external packages we use, only libsodium is available on
> Debian (and older Debian/Ubuntu, as mentioned, have an older version
> that does not have a functionality we require, which is why it is
> included in our source build as well), so that is the only external
> we have that we can plausibly say "we can use the system version",
> because all the others are not available on most systems.

We can package every of those in GNU Guix, there's not as much
bureaucracy as Debian when it comes to inclusion, as long as Free
Software and freedom-non-controversial. The "system" thing is just so
handy for us build-system wise we can just provide it as an input and
it will find things automatically, I don't say that "system" lookup
should imply to take any available library in general, in the context
of GNU Guix we can give it a particular version and stick to it, unlike
Debian's who can't have or with great difficulty, multiple versions of
the same library installed.

Toggle quote (17 lines)
> Also --- we would be somewhat wary of taking the "system"
> `libsecp256k1`, as this is very consensus-critical, and we know that
> our program works with a very specific version, but cannot assure
> this to be true if the "system" `libsecp256k1` is not the exact
> version.
> (Note that we cannot take the `libsecp256k1` from `bitcoin-core`
> because (1) the `bitcoin-core` package uses a vendored
> `libsecp256k1`, the separate Guix `libsecp256k1` is actually only
> used by `electrum` and related projects and (2) the interface
> `bitcoin-core` uses may be different from the interface we use, it
> would require review before we would be able to assure that the
> interfaces they use are exactly the same; this would be mitigated by
> running the full test suite as it also tests consensus-criticality.)
> Is there an easy way to ensure that any `libsecp256k1` that gets fed
> into the `c-lightning` build as an `inputs` is of a specific `git`
> commit?

Yes we can package yet another variant like Bitcoin Core at a specific
commit for c-lightning.

Toggle quote (14 lines)
> Hmm do you mean something like:
>
> (origin
> ; whatever...
> (snippet
> '(begin
> (delete-file-recursively "external/gheap")
> (delete-file-recursively "external/jsmn")
> (delete-file-recursively "external/libbacktrace")
> (delete-file-recursively "external/libsodium")
> (delete-file-recursively "external/libwally-core"))))
>
> ?

Yes!

Toggle quote (3 lines)
> How do you mix in a build system?
> Would `python-pyqt` be a good example of such "mix in"?

Maybe? I'm no expert here.

Toggle quote (3 lines)
> Regards,
> ZmnSCPxj

FYI, I'm not as available for GNU Guix as I'd like, I am looking at the
Python deps, just it will take me some time to actually do it (not at
home now). I see python-mako is already packaged, python-wallycore I am
packaging it, python-mrkd also looking.

Also if we want to provide the Python bindings (?) to c-lightning we
also have the option of creating a separate package based on the same
sources but with different build-system (like python-build-system), and
also it can have c-lightning as an input.

Léo
-----BEGIN PGP SIGNATURE-----

iQIzBAABCgAdFiEEFIvLi9gL+xax3g6RRaix6GvNEKYFAmBUalIACgkQRaix6GvN
EKZmrg//UNk1WwUwLeZlabzdnVwe2athHoxiuI6mN6eeiAXJL+QEmNTvtdPYvvEG
jhIH9oPsUEyE+sSOe2tYLUW5cms0duyf5vsCmgvmCU++WKfeGICntaCstb6GTvMk
VYTyBH2VoCL49bbRNFHXN68iFgz8NFxZmm5DuT3Cj4eTNub20knqXe29947kqvhX
WxMYHcSegjncIAnDbG7VKba+sJeu44uRsgQDVpB09EhPABZIkyN3r7/Zjm8CYLc1
HxP+UKI63a3p6MYccD6wHmdaxoav//vinOw7llggqIZiBHw7FD2HsOt84ZT4ViSD
6c+10XB1WGj9VzBa1oTuGDGjjSCwBjhALn137D9MqimT55uXTJx/hbXirGmQkehj
uBxq/+jcpERcwlPaZfOJNrdP08MgWmnkC/uY2LZ8dBOEPwhcX0OX3U+LXTsOJ6VA
Q3d8qIUJu+Udy66DhL2Z4/HWVhVtvXp8XAVGf6kKNuU5BtZF6grZvRt3ImTUJxW+
D9qRm8TqM2kBctDnAyXQ8umoCZHwdVPdjnN2rKNg/ElEG/Y4Pm52HD3uJx1Q65V4
xynaEBSrW7DSY4nlpQ2HIhwoG9bQIzY5fDIBG4kA4MmZ2ctxJYU1eegM3slxkzBM
iYfwVTgkQ1S5JtDYf1WSyGqfmYsZhB/t9yH+nt8I+6iod6qUASQ=
=hSvx
-----END PGP SIGNATURE-----


Z
Z
ZmnSCPxj wrote on 19 Mar 2021 20:31
(name . Léo Le Bouter)(address . lle-bout@zaclys.net)(name . 47187@debbugs.gnu.org)(address . 47187@debbugs.gnu.org)
SjeqBINTOoa3n9VqlQfXDB9T1V9IuwwKMATmcslp8baQBPODyoG4WdWDe6p9EgD9tORixvYDjBJ6XEG3y3_gpxhaC6_V_c6O69i8M3KLVTI=@protonmail.com
Good morning Leo,

Toggle quote (27 lines)
> On Thu, 2021-03-18 at 16:54 +0000, ZmnSCPxj wrote:
>
> > That would not be simple I think, but let me see what can be done.
> > For one, it would be fairly difficult to test it outside of a patched
> > Guix, as the packages are not usually available in most distros
> > (which is why we ship the source build with them); e.g. we do not
> > know how to actually find the "system" libbacktrace as no existing
> > system I know of actually ships the libbacktrace we use (Debian ships
> > a libbacktrace for android development, and is not the same package
> > as what we use).
> > Of the external packages we use, only libsodium is available on
> > Debian (and older Debian/Ubuntu, as mentioned, have an older version
> > that does not have a functionality we require, which is why it is
> > included in our source build as well), so that is the only external
> > we have that we can plausibly say "we can use the system version",
> > because all the others are not available on most systems.
>
> We can package every of those in GNU Guix, there's not as much
> bureaucracy as Debian when it comes to inclusion, as long as Free
> Software and freedom-non-controversial. The "system" thing is just so
> handy for us build-system wise we can just provide it as an input and
> it will find things automatically, I don't say that "system" lookup
> should imply to take any available library in general, in the context
> of GNU Guix we can give it a particular version and stick to it, unlike
> Debian's who can't have or with great difficulty, multiple versions of
> the same library installed.

Okay.

It is somewhat unclear to me however how to discover where the library is located.
As far as I understand how autotools does it, it looks at some standard locations on `/`, but I am uncertain if that is how it actually works.

For example if `libwally-core` is separately packaged, obviously it would install into a `/gnu/store/*` via a `--prefix` override.
And if the dependent package were using autotools, it is somehow able to magically find where the `lib*.a` file is.
However, C-Lightning does not actually use autotools (its build system predated my participation, I offered to port to autotools but this was declined), so I somehow need to emulate what autotools does in `--use-system-libraries` mode.

I probably have to go hack some autotools package that trivially depends on `libwally-core` and see what the exact shell script is generated.

Toggle quote (5 lines)
> Also if we want to provide the Python bindings (?) to c-lightning we
> also have the option of creating a separate package based on the same
> sources but with different build-system (like python-build-system), and
> also it can have c-lightning as an input.

Note that AFAIK the Python bindings do not actually invoke any of the C-Lightning binaries, they just open the UNIX socket to the c-lightning daemon, so I think there is no need for `c-lightning` itself as an input.

Regards,
ZmnSCPxj
L
L
Léo Le Bouter wrote on 21 Mar 2021 22:42
(name . ZmnSCPxj)(address . ZmnSCPxj@protonmail.com)(name . 47187@debbugs.gnu.org)(address . 47187@debbugs.gnu.org)
2e63a42572d05d3b3b0ecadfb3bf214c719ab560.camel@zaclys.net
Hello!

Toggle quote (21 lines)
> Okay.
>
> It is somewhat unclear to me however how to discover where the
> library is located.
> As far as I understand how autotools does it, it looks at some
> standard locations on `/`, but I am uncertain if that is how it
> actually works.
>
> For example if `libwally-core` is separately packaged, obviously it
> would install into a `/gnu/store/*` via a `--prefix` override.
> And if the dependent package were using autotools, it is somehow able
> to magically find where the `lib*.a` file is.
> However, C-Lightning does not actually use autotools (its build
> system predated my participation, I offered to port to autotools but
> this was declined), so I somehow need to emulate what autotools does
> in `--use-system-libraries` mode.
>
> I probably have to go hack some autotools package that trivially
> depends on `libwally-core` and see what the exact shell script is
> generated.

pkg-config if your deps provide .pc files! Otherwise I am actually not
sure of the lookup strategies.

Toggle quote (5 lines)
> Note that AFAIK the Python bindings do not actually invoke any of the
> C-Lightning binaries, they just open the UNIX socket to the c-
> lightning daemon, so I think there is no need for `c-lightning`
> itself as an input.

Alright!

Toggle quote (3 lines)
> Regards,
> ZmnSCPxj

Léo
-----BEGIN PGP SIGNATURE-----

iQIzBAABCgAdFiEEFIvLi9gL+xax3g6RRaix6GvNEKYFAmBXvbAACgkQRaix6GvN
EKZCgA/+LT7lH7odRu8Z9FW0RAqA7d3g+X/JHz5XKEQ3OaR8JR5GYZtZNDQ+jycf
6CiFRMQtrO+74+1Z9K1PVgHDt5leQP5BHofjMAOBt8HswtL8Y4CqgxijrupgOZYu
BYO9tKU4kq/HJUT3e25cnIlknmssS3cbQ6+bydZ9iZ5I3Oe6VH0Fm7kxqLrGuYQX
EJ4Xs0hcMGSSDUf+7QEpaY+BYQP9NJKK4pL+nSchr7OYXPEK4AinteL5jsaZIgSd
Q1udpHzj5F4GjZbhvJbQUtBbiF/gZWCXPdARBh3U/SMj1TFgIxhV9NHEl9JPxZU1
hIuBPZ9z2V+Pt+8anXsYKqerDPSkAB1swsiQ41DZIux0A4bLw9HAfyxXLVh1MJuh
UZfO5yNToBX+wEs2/hH10xH2URWZA5zoL0bFaLb08ys5U9np5Yz8/Aj+nQjnOr1H
NUUxRfZ2DCT9HX5R76aVRfKHn0cVYI8F2Ah/s8rLk+NzO0lBEEMDC+mY+rA6HN4Y
8At+mT5MUhpqj31NoVezJcTcxZ/QpCcYDMUuLiJZSPFSHRalAEJuHt5DB2v+/zYA
tm4PFYJ1U/IbsKpLmZjQFEVDK4o2VFWlAoAPARbI1RVChpVVBxwK/lMFMSwmxXWV
t/5Tx/O5GEBjoJRskVFS3F8W6VkZ9fikgCTU2W05h3PUHji7oHQ=
=dO1S
-----END PGP SIGNATURE-----


L
L
Léo Le Bouter wrote on 26 Mar 2021 19:13
(name . ZmnSCPxj)(address . ZmnSCPxj@protonmail.com)(name . 47187@debbugs.gnu.org)(address . 47187@debbugs.gnu.org)
a3ac3e2607e852bf23b9d01564608a3dda991043.camel@zaclys.net
Just for your information, I am quite busy on a GNOME upgrade now, we
have the 1.2.1 release soon also, some security issues to solve, I told
you earlier I would help but at the end I think it may come a bit later
rather than sooner. Hang out on the IRC channel #guix on Freenode for
more real-time collaboration if that's of interest to you!
-----BEGIN PGP SIGNATURE-----

iQIyBAABCgAdFiEEFIvLi9gL+xax3g6RRaix6GvNEKYFAmBeJGQACgkQRaix6GvN
EKbXHw/4hrV5NATAcDyhKga4Z/mSCW2iyMIjCo8pEMOtDO3J+iYmp+nJyP2wndA6
PHCwd2M/nXqhDeS9BRm0vfcC4GMuwOQ25lOcuBlLJcBrvTaeqnbeU59TTie8/9tH
zR/7nb3NyULiVWyI16pyLUqhT5FQpWOYhB0sNwyHjjWBywagtnY31hLdG0R2ZIMh
MLkdz3xo7r6lQHGzoEKXiMzBRM9+13TiY2CcN4Mm/uNtsqKt7Lhcv3QiUltSrr0o
PjCkYLyuwpTu5hUvnV4fP9Fg2lsjRoX5cNHQ7JalBL/oDSiYWLzGk0chfBZXySPP
q1K2XvVf3IRn78Eczlx3KWrH1RB6wud6VqMHjWlaNe2A4+qPaieSX75SKCtoWoLm
5WYgf1bPMuDuYZmvOC2xgE1QkY/Qtm1OANPCD6G/Vg8MqevMjdSyiVhNXhwxRce5
pZG4aBVOXLDrI8cMFZU+21VnB2lXIl4dyjCZRdWRxEFzOFQHQG017pyNovqwmOYl
8D3/uoMrPYuoY72bBXTG51EKhyegT5XzV+snn5FNPUOf6hk1FsSrkNQbqIhMpzdD
3pHvAk5i3dnFI+IpUDb42u0nA7syv4ILVuIVc3R6az7OL+Q6da8DQdUHeB/mS/cA
cUtgcoPI6fbr5b9NN39+GrvrnwUU5lGa92EBTH+yho0gTsOVxQ==
=qZOo
-----END PGP SIGNATURE-----


?