From 77f02ddb69ce7b2abe45c975859e1d67e81021d3 Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Wed, 18 Sep 2024 15:15:55 +0200 Subject: [PATCH 01/11] multi: bump lnd to latest master version --- go.mod | 31 +++++++++--------- go.sum | 61 +++++++++++++++++++----------------- lightning_client.go | 2 +- macaroon_recipes.go | 2 +- router_client.go | 66 +++++++++++++++++++++++++++++++++++++++ testdata/permissions.json | 16 ++++++++++ tools/Dockerfile | 2 +- 7 files changed, 134 insertions(+), 46 deletions(-) diff --git a/go.mod b/go.mod index c710b436..2a964103 100644 --- a/go.mod +++ b/go.mod @@ -1,16 +1,16 @@ module github.com/lightninglabs/lndclient require ( - github.com/btcsuite/btcd v0.24.2-beta.rc1.0.20240403021926-ae5533602c46 + github.com/btcsuite/btcd v0.24.2-beta.rc1.0.20240625142744-cc26860b4026 github.com/btcsuite/btcd/btcec/v2 v2.3.3 github.com/btcsuite/btcd/btcutil v1.1.5 github.com/btcsuite/btcd/btcutil/psbt v1.1.8 github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f - github.com/btcsuite/btcwallet v0.16.10-0.20240404104514-b2f31f9045fb + github.com/btcsuite/btcwallet v0.16.10-0.20240809133323-7d3434c65ae2 github.com/btcsuite/btcwallet/wtxmgr v1.5.3 - github.com/lightningnetwork/lnd v0.18.0-beta.1 - github.com/lightningnetwork/lnd/kvdb v1.4.8 + github.com/lightningnetwork/lnd v0.18.0-beta.rc4.0.20240919095711-611852fd34b1 + github.com/lightningnetwork/lnd/kvdb v1.4.10 github.com/stretchr/testify v1.9.0 google.golang.org/grpc v1.59.0 gopkg.in/macaroon-bakery.v2 v2.0.1 @@ -76,9 +76,10 @@ require ( github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect github.com/jackc/pgtype v1.14.0 // indirect github.com/jackc/pgx/v4 v4.18.2 // indirect + github.com/jackc/pgx/v5 v5.3.1 // indirect github.com/jessevdk/go-flags v1.4.0 // indirect github.com/jonboulle/clockwork v0.2.2 // indirect - github.com/jrick/logrotate v1.0.0 // indirect + github.com/jrick/logrotate v1.1.2 // indirect github.com/json-iterator/go v1.1.11 // indirect github.com/juju/clock v0.0.0-20220203021603-d9deb868a28a // indirect github.com/juju/collections v0.0.0-20220203020748-febd7cad8a7a // indirect @@ -89,18 +90,19 @@ require ( github.com/juju/utils/v3 v3.0.0-20220203023959-c3fbc78a33b0 // indirect github.com/juju/version/v2 v2.0.0-20220204124744-fc9915e3d935 // indirect github.com/kkdai/bstream v1.0.0 // indirect + github.com/klauspost/compress v1.17.9 // indirect github.com/lib/pq v1.10.9 // indirect github.com/lightninglabs/gozmq v0.0.0-20191113021534-d20a764486bf // indirect github.com/lightninglabs/neutrino v0.16.1-0.20240425105051-602843d34ffd // indirect github.com/lightninglabs/neutrino/cache v1.1.2 // indirect - github.com/lightningnetwork/lightning-onion v1.2.1-0.20230823005744-06182b1d7d2f // indirect + github.com/lightningnetwork/lightning-onion v1.2.1-0.20240712235311-98bd56499dfb // indirect github.com/lightningnetwork/lnd/clock v1.1.1 // indirect - github.com/lightningnetwork/lnd/fn v1.0.5 // indirect - github.com/lightningnetwork/lnd/healthcheck v1.2.4 // indirect + github.com/lightningnetwork/lnd/fn v1.2.1 // indirect + github.com/lightningnetwork/lnd/healthcheck v1.2.5 // indirect github.com/lightningnetwork/lnd/queue v1.1.1 // indirect - github.com/lightningnetwork/lnd/sqldb v1.0.2 // indirect + github.com/lightningnetwork/lnd/sqldb v1.0.4 // indirect github.com/lightningnetwork/lnd/ticker v1.1.1 // indirect - github.com/lightningnetwork/lnd/tlv v1.2.3 // indirect + github.com/lightningnetwork/lnd/tlv v1.2.6 // indirect github.com/lightningnetwork/lnd/tor v1.1.2 // indirect github.com/ltcsuite/ltcd v0.0.0-20190101042124-f37f8bf35796 // indirect github.com/mattn/go-isatty v0.0.20 // indirect @@ -156,7 +158,8 @@ require ( golang.org/x/crypto v0.22.0 // indirect golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 // indirect golang.org/x/mod v0.16.0 // indirect - golang.org/x/net v0.23.0 // indirect + golang.org/x/net v0.24.0 // indirect + golang.org/x/sync v0.7.0 // indirect golang.org/x/sys v0.19.0 // indirect golang.org/x/term v0.19.0 // indirect golang.org/x/text v0.14.0 // indirect @@ -174,7 +177,7 @@ require ( modernc.org/libc v1.49.3 // indirect modernc.org/mathutil v1.6.0 // indirect modernc.org/memory v1.8.0 // indirect - modernc.org/sqlite v1.29.8 // indirect + modernc.org/sqlite v1.29.10 // indirect modernc.org/strutil v1.2.0 // indirect modernc.org/token v1.1.0 // indirect sigs.k8s.io/yaml v1.2.0 // indirect @@ -184,6 +187,6 @@ require ( // allows us to specify that as an option. replace google.golang.org/protobuf => github.com/lightninglabs/protobuf-go-hex-display v1.30.0-hex-display -go 1.21.4 +go 1.22.6 -toolchain go1.22.2 +toolchain go1.22.7 diff --git a/go.sum b/go.sum index 6072967b..ab0c7a3e 100644 --- a/go.sum +++ b/go.sum @@ -64,8 +64,8 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c/go.mod h1:tjmYdS6MLJ5/s0Fj4DbLgSbDHbEqLJrtnHecBFkdz5M= github.com/btcsuite/btcd v0.23.5-0.20231215221805-96c9fd8078fd/go.mod h1:nm3Bko6zh6bWP60UxwoT5LzdGJsQJaPo6HjduXq9p6A= -github.com/btcsuite/btcd v0.24.2-beta.rc1.0.20240403021926-ae5533602c46 h1:tjpNTdZNQqE14menwDGAxWfzN0DFHVTXFEyEL8yvA/4= -github.com/btcsuite/btcd v0.24.2-beta.rc1.0.20240403021926-ae5533602c46/go.mod h1:5C8ChTkl5ejr3WHj8tkQSCmydiMEPB0ZhQhehpq7Dgg= +github.com/btcsuite/btcd v0.24.2-beta.rc1.0.20240625142744-cc26860b4026 h1:s8/96vQSj05bqLl9RyM/eMX8gLtiayEj520TVE4YGy0= +github.com/btcsuite/btcd v0.24.2-beta.rc1.0.20240625142744-cc26860b4026/go.mod h1:5C8ChTkl5ejr3WHj8tkQSCmydiMEPB0ZhQhehpq7Dgg= github.com/btcsuite/btcd/btcec/v2 v2.1.0/go.mod h1:2VzYrv4Gm4apmbVVsSq5bqf1Ec8v56E48Vt0Y/umPgA= github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= github.com/btcsuite/btcd/btcec/v2 v2.3.3 h1:6+iXlDKE8RMtKsvK0gshlXIuPbyWM/h84Ensb7o3sC0= @@ -83,8 +83,8 @@ github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0/go.mod h1:7SFka0XMvUgj3hfZtyd github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f h1:bAs4lUbRJpnnkd9VhRV3jjAVU7DJVjMaK+IsvSeZvFo= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= -github.com/btcsuite/btcwallet v0.16.10-0.20240404104514-b2f31f9045fb h1:qoIOlBPRZWtfpcbQlNFf67Wz8ZlXo+mxQc9Pnbm/iqU= -github.com/btcsuite/btcwallet v0.16.10-0.20240404104514-b2f31f9045fb/go.mod h1:2C3Q/MhYAKmk7F+Tey6LfKtKRTdQsrCf8AAAzzDPmH4= +github.com/btcsuite/btcwallet v0.16.10-0.20240809133323-7d3434c65ae2 h1:qa4Avm7p97JroZZyMJADbEb9u853pjleJYSeitENvLc= +github.com/btcsuite/btcwallet v0.16.10-0.20240809133323-7d3434c65ae2/go.mod h1:X2xDre+j1QphTRo54y2TikUzeSvreL1t1aMXrD8Kc5A= github.com/btcsuite/btcwallet/wallet/txauthor v1.3.4 h1:poyHFf7+5+RdxNp5r2T6IBRD7RyraUsYARYbp/7t4D8= github.com/btcsuite/btcwallet/wallet/txauthor v1.3.4/go.mod h1:GETGDQuyq+VFfH1S/+/7slLM/9aNa4l7P4ejX6dJfb0= github.com/btcsuite/btcwallet/wallet/txrules v1.2.1 h1:UZo7YRzdHbwhK7Rhv3PO9bXgTxiOH45edK5qdsdiatk= @@ -357,6 +357,8 @@ github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQ github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs= github.com/jackc/pgx/v4 v4.18.2 h1:xVpYkNR5pk5bMCZGfClbO962UIqVABcAGt7ha1s/FeU= github.com/jackc/pgx/v4 v4.18.2/go.mod h1:Ey4Oru5tH5sB6tV7hDmfWFahwF15Eb7DNXlRKx2CkVw= +github.com/jackc/pgx/v5 v5.3.1 h1:Fcr8QJ1ZeLi5zsPZqQeUZhNhxfkkKBOgJuYkJHoBOtU= +github.com/jackc/pgx/v5 v5.3.1/go.mod h1:t3JDKnCBlYIc0ewLF0Q7B8MXmoIaBOZj/ic7iHozM/8= github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= @@ -366,8 +368,9 @@ github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJS github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ= github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/jrick/logrotate v1.0.0 h1:lQ1bL/n9mBNeIXoTUoYRlK4dHuNJVofX9oWqBtPnSzI= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/jrick/logrotate v1.1.2 h1:6ePk462NCX7TfKtNp5JJ7MbA2YIslkpfgP03TlTYMN0= +github.com/jrick/logrotate v1.1.2/go.mod h1:f9tdWggSVK3iqavGpyvegq5IhNois7KXmasU6/N96OQ= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ= @@ -400,6 +403,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= github.com/kkdai/bstream v1.0.0 h1:Se5gHwgp2VT2uHfDrkbbgbgEvV9cimLELwrPJctSjg8= github.com/kkdai/bstream v1.0.0/go.mod h1:FDnDOHt5Yx4p3FaHcioFT0QjDOtgUpvjeZqAs+NVZZA= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -427,26 +432,26 @@ github.com/lightninglabs/neutrino/cache v1.1.2 h1:C9DY/DAPaPxbFC+xNNEI/z1SJY9GS3 github.com/lightninglabs/neutrino/cache v1.1.2/go.mod h1:XJNcgdOw1LQnanGjw8Vj44CvguYA25IMKjWFZczwZuo= github.com/lightninglabs/protobuf-go-hex-display v1.30.0-hex-display h1:pRdza2wleRN1L2fJXd6ZoQ9ZegVFTAb2bOQfruJPKcY= github.com/lightninglabs/protobuf-go-hex-display v1.30.0-hex-display/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -github.com/lightningnetwork/lightning-onion v1.2.1-0.20230823005744-06182b1d7d2f h1:Pua7+5TcFEJXIIZ1I2YAUapmbcttmLj4TTi786bIi3s= -github.com/lightningnetwork/lightning-onion v1.2.1-0.20230823005744-06182b1d7d2f/go.mod h1:c0kvRShutpj3l6B9WtTsNTBUtjSmjZXbJd9ZBRQOSKI= -github.com/lightningnetwork/lnd v0.18.0-beta.1 h1:7DpRre4rtUmLim4JC5oPd3KEd1Q3QpWTH6jQgSOGNYM= -github.com/lightningnetwork/lnd v0.18.0-beta.1/go.mod h1:1SA9iv9rZddNAcfP38SN9lNSVT1zf5aqmukLUoomjDU= +github.com/lightningnetwork/lightning-onion v1.2.1-0.20240712235311-98bd56499dfb h1:yfM05S8DXKhuCBp5qSMZdtSwvJ+GFzl94KbXMNB1JDY= +github.com/lightningnetwork/lightning-onion v1.2.1-0.20240712235311-98bd56499dfb/go.mod h1:c0kvRShutpj3l6B9WtTsNTBUtjSmjZXbJd9ZBRQOSKI= +github.com/lightningnetwork/lnd v0.18.0-beta.rc4.0.20240919095711-611852fd34b1 h1:MPShouzqsQHRwgvzcfJnTl5qTi4d9rR0jrnglUemvoQ= +github.com/lightningnetwork/lnd v0.18.0-beta.rc4.0.20240919095711-611852fd34b1/go.mod h1:Y4sP4cQS+V8IpDn6hD6zEyX3dkIwUqLkCPtHfXNaVY0= github.com/lightningnetwork/lnd/clock v1.1.1 h1:OfR3/zcJd2RhH0RU+zX/77c0ZiOnIMsDIBjgjWdZgA0= github.com/lightningnetwork/lnd/clock v1.1.1/go.mod h1:mGnAhPyjYZQJmebS7aevElXKTFDuO+uNFFfMXK1W8xQ= -github.com/lightningnetwork/lnd/fn v1.0.5 h1:ffDgMSn83avw6rNzxhbt6w5/2oIrwQKTPGfyaLupZtE= -github.com/lightningnetwork/lnd/fn v1.0.5/go.mod h1:P027+0CyELd92H9gnReUkGGAqbFA1HwjHWdfaDFD51U= -github.com/lightningnetwork/lnd/healthcheck v1.2.4 h1:lLPLac+p/TllByxGSlkCwkJlkddqMP5UCoawCj3mgFQ= -github.com/lightningnetwork/lnd/healthcheck v1.2.4/go.mod h1:G7Tst2tVvWo7cx6mSBEToQC5L1XOGxzZTPB29g9Rv2I= -github.com/lightningnetwork/lnd/kvdb v1.4.8 h1:xH0a5Vi1yrcZ5BEeF2ba3vlKBRxrL9uYXlWTjOjbNTY= -github.com/lightningnetwork/lnd/kvdb v1.4.8/go.mod h1:J2diNABOoII9UrMnxXS5w7vZwP7CA1CStrl8MnIrb3A= +github.com/lightningnetwork/lnd/fn v1.2.1 h1:pPsVGrwi9QBwdLJzaEGK33wmiVKOxs/zc8H7+MamFf0= +github.com/lightningnetwork/lnd/fn v1.2.1/go.mod h1:SyFohpVrARPKH3XVAJZlXdVe+IwMYc4OMAvrDY32kw0= +github.com/lightningnetwork/lnd/healthcheck v1.2.5 h1:aTJy5xeBpcWgRtW/PGBDe+LMQEmNm/HQewlQx2jt7OA= +github.com/lightningnetwork/lnd/healthcheck v1.2.5/go.mod h1:G7Tst2tVvWo7cx6mSBEToQC5L1XOGxzZTPB29g9Rv2I= +github.com/lightningnetwork/lnd/kvdb v1.4.10 h1:vK89IVv1oVH9ubQWU+EmoCQFeVRaC8kfmOrqHbY5zoY= +github.com/lightningnetwork/lnd/kvdb v1.4.10/go.mod h1:J2diNABOoII9UrMnxXS5w7vZwP7CA1CStrl8MnIrb3A= github.com/lightningnetwork/lnd/queue v1.1.1 h1:99ovBlpM9B0FRCGYJo6RSFDlt8/vOkQQZznVb18iNMI= github.com/lightningnetwork/lnd/queue v1.1.1/go.mod h1:7A6nC1Qrm32FHuhx/mi1cieAiBZo5O6l8IBIoQxvkz4= -github.com/lightningnetwork/lnd/sqldb v1.0.2 h1:PfuYzScYMD9/QonKo/QvgsbXfTnH5DfldIimkfdW4Bk= -github.com/lightningnetwork/lnd/sqldb v1.0.2/go.mod h1:V2Xl6JNWLTKE97WJnwfs0d0TYJdIQTqK8/3aAwkd3qI= +github.com/lightningnetwork/lnd/sqldb v1.0.4 h1:9cMwPxcrLQG8UmyZO4q8SpR7NmxSwBMbj3AispdcwHg= +github.com/lightningnetwork/lnd/sqldb v1.0.4/go.mod h1:4cQOkdymlZ1znnjuRNvMoatQGJkRneTj2CoPSPaQhWo= github.com/lightningnetwork/lnd/ticker v1.1.1 h1:J/b6N2hibFtC7JLV77ULQp++QLtCwT6ijJlbdiZFbSM= github.com/lightningnetwork/lnd/ticker v1.1.1/go.mod h1:waPTRAAcwtu7Ji3+3k+u/xH5GHovTsCoSVpho0KDvdA= -github.com/lightningnetwork/lnd/tlv v1.2.3 h1:If5ibokA/UoCBGuCKaY6Vn2SJU0l9uAbehCnhTZjEP8= -github.com/lightningnetwork/lnd/tlv v1.2.3/go.mod h1:zDkmqxOczP6LaLTvSFDQ1SJUfHcQRCMKFj93dn3eMB8= +github.com/lightningnetwork/lnd/tlv v1.2.6 h1:icvQG2yDr6k3ZuZzfRdG3EJp6pHurcuh3R6dg0gv/Mw= +github.com/lightningnetwork/lnd/tlv v1.2.6/go.mod h1:/CmY4VbItpOldksocmGT4lxiJqRP9oLxwSZOda2kzNQ= github.com/lightningnetwork/lnd/tor v1.1.2 h1:3zv9z/EivNFaMF89v3ciBjCS7kvCj4ZFG7XvD2Qq0/k= github.com/lightningnetwork/lnd/tor v1.1.2/go.mod h1:j7T9uJ2NLMaHwE7GiBGnpYLn4f7NRoTM6qj+ul6/ycA= github.com/ltcsuite/ltcd v0.0.0-20190101042124-f37f8bf35796 h1:sjOGyegMIhvgfq5oaue6Td+hxZuf3tDC8lAPrFldqFw= @@ -462,8 +467,6 @@ github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= -github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/miekg/dns v1.1.43 h1:JKfpVSCB84vrAmHzyrsxB5NAr5kLoMXZArPSw7Qlgyg= @@ -538,8 +541,8 @@ github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qq github.com/rogpeppe/fastuuid v1.2.0 h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi2s= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= @@ -739,8 +742,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -760,8 +763,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1037,8 +1040,8 @@ modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc= modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss= -modernc.org/sqlite v1.29.8 h1:nGKglNx9K5v0As+zF0/Gcl1kMkmaU1XynYyq92PbsC8= -modernc.org/sqlite v1.29.8/go.mod h1:lQPm27iqa4UNZpmr4Aor0MH0HkCLbt1huYDfWylLZFk= +modernc.org/sqlite v1.29.10 h1:3u93dz83myFnMilBGCOLbr+HjklS6+5rJLx4q86RDAg= +modernc.org/sqlite v1.29.10/go.mod h1:ItX2a1OVGgNsFh6Dv60JQvGfJfTPHPVpV6DF59akYOA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/lightning_client.go b/lightning_client.go index bc59f8e3..d5074937 100644 --- a/lightning_client.go +++ b/lightning_client.go @@ -882,7 +882,7 @@ func newNode(lnNode *lnrpc.LightningNode) (*Node, error) { ) } - for i := 0; i < len(lnNode.Addresses); i++ { + for i := range lnNode.Addresses { node.Addresses[i] = lnNode.Addresses[i].Addr } diff --git a/macaroon_recipes.go b/macaroon_recipes.go index c90a660f..ed15d463 100644 --- a/macaroon_recipes.go +++ b/macaroon_recipes.go @@ -69,7 +69,7 @@ func MacaroonRecipe(c LightningClient, packages []string) ([]MacaroonPermission, // and what methods it declares. ifaceType := reflect.TypeOf(ifacePtr).Elem() serverName := strings.ReplaceAll(ifaceType.Name(), "Client", "") - for i := 0; i < ifaceType.NumMethod(); i++ { + for i := range ifaceType.NumMethod() { // The methods in lndclient might be called slightly // differently. Rename according to our rename mapping // table. diff --git a/router_client.go b/router_client.go index 5cc841d6..cee3d1d3 100644 --- a/router_client.go +++ b/router_client.go @@ -73,6 +73,20 @@ type RouterClient interface { // (enabled, disabled, or auto). UpdateChanStatus(ctx context.Context, channel *wire.OutPoint, action routerrpc.ChanStatusAction) error + + // XAddLocalChanAlias is an experimental method that allows the caller + // to add a local channel alias to the router. This is only a locally + // stored alias, and will not be communicated to the channel peer via + // any message. Therefore, routing over such an alias will only work if + // the peer also calls this same RPC on their end. + XAddLocalChanAlias(ctx context.Context, alias, + baseScid lnwire.ShortChannelID) error + + // XDeleteLocalChanAlias is an experimental method that allows the + // caller to remove a local channel alias in the router. The deletion + // will not be communicated to the channel peer via any message. + XDeleteLocalChanAlias(ctx context.Context, alias, + baseScid lnwire.ShortChannelID) error } // PaymentStatus describe the state of a payment. @@ -1050,3 +1064,55 @@ func (r *routerClient) UpdateChanStatus(ctx context.Context, ) return err } + +// XAddLocalChanAlias is an experimental method that allows the caller +// to add a local channel alias to the router. This is only a locally +// stored alias, and will not be communicated to the channel peer via +// any message. Therefore, routing over such an alias will only work if +// the peer also calls this same RPC on their end. +func (r *routerClient) XAddLocalChanAlias(ctx context.Context, alias, + baseScid lnwire.ShortChannelID) error { + + rpcCtx, cancel := context.WithTimeout(ctx, r.timeout) + defer cancel() + + _, err := r.client.XAddLocalChanAliases( + r.routerKitMac.WithMacaroonAuth(rpcCtx), + &routerrpc.AddAliasesRequest{ + AliasMaps: []*lnrpc.AliasMap{ + { + BaseScid: baseScid.ToUint64(), + Aliases: []uint64{ + alias.ToUint64(), + }, + }, + }, + }, + ) + return err +} + +// XDeleteLocalChanAlias is an experimental method that allows the +// caller to remove a local channel alias in the router. The deletion +// will not be communicated to the channel peer via any message. +func (r *routerClient) XDeleteLocalChanAlias(ctx context.Context, alias, + baseScid lnwire.ShortChannelID) error { + + rpcCtx, cancel := context.WithTimeout(ctx, r.timeout) + defer cancel() + + _, err := r.client.XDeleteLocalChanAliases( + r.routerKitMac.WithMacaroonAuth(rpcCtx), + &routerrpc.DeleteAliasesRequest{ + AliasMaps: []*lnrpc.AliasMap{ + { + BaseScid: baseScid.ToUint64(), + Aliases: []uint64{ + alias.ToUint64(), + }, + }, + }, + }, + ) + return err +} diff --git a/testdata/permissions.json b/testdata/permissions.json index e3cc55b8..acbbba75 100644 --- a/testdata/permissions.json +++ b/testdata/permissions.json @@ -880,6 +880,22 @@ } ] }, + "/routerrpc.Router/XAddLocalChanAlias": { + "permissions": [ + { + "entity": "offchain", + "action": "write" + } + ] + }, + "/routerrpc.Router/XDeleteLocalChanAlias": { + "permissions": [ + { + "entity": "offchain", + "action": "write" + } + ] + }, "/signrpc.Signer/ComputeInputScript": { "permissions": [ { diff --git a/tools/Dockerfile b/tools/Dockerfile index 17555ef1..03a27689 100644 --- a/tools/Dockerfile +++ b/tools/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.22.3-bookworm +FROM golang:1.22.6-bookworm RUN apt-get update && apt-get install -y git ENV GOCACHE=/tmp/build/.cache From 89ef128f3d805bbc4b31c44f7c49bcdb409d3ec9 Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Wed, 18 Sep 2024 15:15:56 +0200 Subject: [PATCH 02/11] lightning+router: add custom channel data fields --- lightning_client.go | 67 +++++++++++++++++++++++++++++++++------------ router_client.go | 23 ++++++++++------ 2 files changed, 64 insertions(+), 26 deletions(-) diff --git a/lightning_client.go b/lightning_client.go index d5074937..62f58b69 100644 --- a/lightning_client.go +++ b/lightning_client.go @@ -424,6 +424,10 @@ type ChannelInfo struct { // AliasScids contains a list of alias short channel identifiers that // may be used for this channel. This array can be empty. AliasScids []uint64 + + // CustomChannelData is an optional field that can be used to store + // data for custom channels. + CustomChannelData []byte } func (s *lightningClient) newChannelInfo(channel *lnrpc.Channel) (*ChannelInfo, @@ -465,8 +469,9 @@ func (s *lightningClient) newChannelInfo(channel *lnrpc.Channel) (*ChannelInfo, RemoteConstraints: newChannelConstraint( channel.RemoteConstraints, ), - ZeroConf: channel.ZeroConf, - ZeroConfScid: channel.ZeroConfConfirmedScid, + ZeroConf: channel.ZeroConf, + ZeroConfScid: channel.ZeroConfConfirmedScid, + CustomChannelData: channel.CustomChannelData, } chanInfo.AliasScids = make([]uint64, len(channel.AliasScids)) @@ -834,6 +839,10 @@ type ChannelBalance struct { // PendingBalance is the sum of all pending channel balances. PendingBalance btcutil.Amount + + // CustomChannelData is an optional field that can be used to store + // data for custom channels. + CustomChannelData []byte } // Node describes a node in the network. @@ -1679,6 +1688,10 @@ type InvoiceHtlc struct { // CustomRecords is list of the custom tlv records. CustomRecords map[uint64][]byte + + // CustomChannelData is an optional field that can be used to store + // data for custom channels. + CustomChannelData []byte } // PendingHtlc represents a HTLC that is currently pending on some channel. @@ -1777,10 +1790,13 @@ func unmarshalInvoice(resp *lnrpc.Invoice) (*Invoice, error) { for i, htlc := range resp.Htlcs { invoiceHtlc := InvoiceHtlc{ - ChannelID: lnwire.NewShortChanIDFromInt(htlc.ChanId), - Amount: lnwire.MilliSatoshi(htlc.AmtMsat), - CustomRecords: htlc.CustomRecords, - State: htlc.State, + ChannelID: lnwire.NewShortChanIDFromInt( + htlc.ChanId, + ), + Amount: lnwire.MilliSatoshi(htlc.AmtMsat), + CustomRecords: htlc.CustomRecords, + State: htlc.State, + CustomChannelData: htlc.CustomChannelData, } if htlc.AcceptTime != 0 { @@ -1971,6 +1987,10 @@ type PendingChannel struct { // ChannelInitiator indicates which party opened the channel. ChannelInitiator Initiator + + // CustomChannelData is an optional field that can be used to store + // data for custom channels. + CustomChannelData []byte } // NewPendingChannel creates a pending channel from the rpc struct. @@ -1993,12 +2013,13 @@ func NewPendingChannel(channel *lnrpc.PendingChannelsResponse_PendingChannel) ( } return &PendingChannel{ - ChannelPoint: outpoint, - PubKeyBytes: peer, - Capacity: btcutil.Amount(channel.Capacity), - LocalBalance: btcutil.Amount(channel.LocalBalance), - RemoteBalance: btcutil.Amount(channel.RemoteBalance), - ChannelInitiator: initiator, + ChannelPoint: outpoint, + PubKeyBytes: peer, + Capacity: btcutil.Amount(channel.Capacity), + LocalBalance: btcutil.Amount(channel.LocalBalance), + RemoteBalance: btcutil.Amount(channel.RemoteBalance), + ChannelInitiator: initiator, + CustomChannelData: channel.CustomChannelData, }, nil } @@ -2473,6 +2494,10 @@ type Payment struct { // SequenceNumber is a unique id for each payment. SequenceNumber uint64 + + // FirstHopCustomRecords holds the custom TLV records that were sent to + // the first hop as part of the wire message. + FirstHopCustomRecords map[uint64][]byte } // ListPaymentsRequest contains the request parameters for a paginated @@ -2540,9 +2565,14 @@ func (s *lightningClient) ListPayments(ctx context.Context, PaymentRequest: payment.PaymentRequest, Status: status, Htlcs: payment.Htlcs, - Amount: lnwire.MilliSatoshi(payment.ValueMsat), - Fee: lnwire.MilliSatoshi(payment.FeeMsat), - SequenceNumber: payment.PaymentIndex, + Amount: lnwire.MilliSatoshi( + payment.ValueMsat, + ), + Fee: lnwire.MilliSatoshi( + payment.FeeMsat, + ), + SequenceNumber: payment.PaymentIndex, + FirstHopCustomRecords: payment.FirstHopCustomRecords, } // Add our preimage if it is known. @@ -3454,8 +3484,11 @@ func (s *lightningClient) ChannelBalance(ctx context.Context) (*ChannelBalance, } return &ChannelBalance{ - Balance: btcutil.Amount(resp.Balance), // nolint:staticcheck - PendingBalance: btcutil.Amount(resp.PendingOpenBalance), // nolint:staticcheck + //nolint:staticcheck + Balance: btcutil.Amount(resp.Balance), + //nolint:staticcheck + PendingBalance: btcutil.Amount(resp.PendingOpenBalance), + CustomChannelData: resp.CustomChannelData, }, nil } diff --git a/router_client.go b/router_client.go index cee3d1d3..b22da6a1 100644 --- a/router_client.go +++ b/router_client.go @@ -298,6 +298,10 @@ type SendPaymentRequest struct { // AMP is set to true if the payment should be an AMP payment. AMP bool + + // FirstHopCustomRecords holds the custom TLV records should be sent to + // the first hop as part of the wire message. + FirstHopCustomRecords map[uint64][]byte } // InterceptedHtlc contains information about a htlc that was intercepted in @@ -408,15 +412,16 @@ func (r *routerClient) SendPayment(ctx context.Context, rpcCtx := r.routerKitMac.WithMacaroonAuth(ctx) rpcReq := &routerrpc.SendPaymentRequest{ - FeeLimitSat: int64(request.MaxFee), - FeeLimitMsat: int64(request.MaxFeeMsat), - PaymentRequest: request.Invoice, - TimeoutSeconds: int32(request.Timeout.Seconds()), - MaxParts: request.MaxParts, - OutgoingChanIds: request.OutgoingChanIds, - AllowSelfPayment: request.AllowSelfPayment, - Amp: request.AMP, - TimePref: request.TimePref, + FeeLimitSat: int64(request.MaxFee), + FeeLimitMsat: int64(request.MaxFeeMsat), + PaymentRequest: request.Invoice, + TimeoutSeconds: int32(request.Timeout.Seconds()), + MaxParts: request.MaxParts, + OutgoingChanIds: request.OutgoingChanIds, + AllowSelfPayment: request.AllowSelfPayment, + Amp: request.AMP, + TimePref: request.TimePref, + FirstHopCustomRecords: request.FirstHopCustomRecords, } if request.MaxCltv != nil { rpcReq.CltvLimit = *request.MaxCltv From 6e6b009d4157138a5f20d9ef780272bb5c2d09ca Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Wed, 18 Sep 2024 15:15:57 +0200 Subject: [PATCH 03/11] lnd_services: allow chain sync interval to be customized To avoid needing to wait a full 5 seconds to re-try checking lnd's status, we allow passing in a custom poll interval. This significantly speeds up some integration tests. --- lnd_services.go | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/lnd_services.go b/lnd_services.go index 087e65b4..1d634ca9 100644 --- a/lnd_services.go +++ b/lnd_services.go @@ -152,6 +152,10 @@ type LndServicesConfig struct { // calls to lnd. If this value is not set, it will default to 30 // seconds. RPCTimeout time.Duration + + // ChainSyncPollInterval is the interval in which we poll the GetInfo + // call to find out if lnd is fully synced to its chain backend. + ChainSyncPollInterval time.Duration } // DialerFunc is a function that is used as grpc.WithContextDialer(). @@ -285,7 +289,8 @@ func NewLndServices(cfg *LndServicesConfig) (*GrpcLndServices, error) { readonlyMac = serializedMacaroon(cfg.CustomMacaroonHex) } else { readonlyMac, err = loadMacaroon( - macaroonDir, string(ReadOnlyServiceMac), cfg.CustomMacaroonPath, + macaroonDir, string(ReadOnlyServiceMac), + cfg.CustomMacaroonPath, ) if err != nil { return nil, err @@ -297,6 +302,10 @@ func NewLndServices(cfg *LndServicesConfig) (*GrpcLndServices, error) { timeout = cfg.RPCTimeout } + if cfg.ChainSyncPollInterval == 0 { + cfg.ChainSyncPollInterval = chainSyncPollInterval + } + basicClient := lnrpc.NewLightningClient(conn) stateClient := newStateClient(conn, readonlyMac) versionerClient := newVersionerClient(conn, readonlyMac, timeout) @@ -413,7 +422,9 @@ func NewLndServices(cfg *LndServicesConfig) (*GrpcLndServices, error) { log.Infof("Waiting for lnd to be fully synced to its chain " + "backend, this might take a while") - err := services.waitForChainSync(cfg.CallerCtx, timeout) + err := services.waitForChainSync( + cfg.CallerCtx, timeout, cfg.ChainSyncPollInterval, + ) if err != nil { cleanup() return nil, fmt.Errorf("error waiting for chain to "+ @@ -453,7 +464,7 @@ func (s *GrpcLndServices) Close() { // synced to its chain backend. This could theoretically take hours if the // initial block download is still in progress. func (s *GrpcLndServices) waitForChainSync(ctx context.Context, - timeout time.Duration) error { + timeout, pollInterval time.Duration) error { mainCtx := ctx if mainCtx == nil { @@ -488,7 +499,7 @@ func (s *GrpcLndServices) waitForChainSync(ctx context.Context, select { // If we're not yet done, let's now wait a few seconds. - case <-time.After(chainSyncPollInterval): + case <-time.After(pollInterval): // If the user cancels the context, we should also // abort the wait. From 11a49f1e48c931de28a932f602292147c5807e05 Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Wed, 18 Sep 2024 15:18:46 +0200 Subject: [PATCH 04/11] router: add resume modified response and fields --- router_client.go | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/router_client.go b/router_client.go index b22da6a1..10164064 100644 --- a/router_client.go +++ b/router_client.go @@ -337,6 +337,10 @@ type InterceptedHtlc struct { // OnionBlob is the onion blob for the next hop. OnionBlob []byte + + // InWireCustomRecords are custom records sent by the sender that were + // only present in the wire message and not the onion itself. + InWireCustomRecords map[uint64][]byte } // HtlcInterceptHandler is a function signature for handling code for htlc @@ -360,6 +364,10 @@ const ( // InterceptorActionResume indicates that an intercepted hltc should be // resumed as normal. InterceptorActionResume + + // InterceptorActionResumeModified indicates that an intercepted hltc + // should be resumed as normal, but with modifications. + InterceptorActionResumeModified ) // InterceptedHtlcResponse contains the actions that must be taken for an @@ -372,6 +380,19 @@ type InterceptedHtlcResponse struct { // Action is the action that should be taken for the htlc that is // intercepted. Action InterceptorAction + + // IncomingAmount is the amount that should be used to validate the + // incoming htlc. This might be different from the actual HTLC amount + // for custom channels. + IncomingAmount lnwire.MilliSatoshi + + // OutgoingAmount is the amount that should be set on the HTLC that is + // forwarded. + OutgoingAmount lnwire.MilliSatoshi + + // CustomRecords are the custom records that should be added to the + // outgoing/forwarded HTLC. + CustomRecords map[uint64][]byte } // routerClient is a wrapper around the generated routerrpc proxy. @@ -790,6 +811,7 @@ func (r *routerClient) InterceptHtlcs(ctx context.Context, chanOut := lnwire.NewShortChanIDFromInt( request.OutgoingRequestedChanId, ) + inWireCustomRecords := request.InWireCustomRecords req := InterceptedHtlc{ IncomingCircuitKey: invpkg.CircuitKey{ @@ -808,6 +830,7 @@ func (r *routerClient) InterceptHtlcs(ctx context.Context, OutgoingChannelID: chanOut, CustomRecords: request.CustomRecords, OnionBlob: request.OnionBlob, + InWireCustomRecords: inWireCustomRecords, } // Try to send our interception request, failing on @@ -907,6 +930,14 @@ func rpcInterceptorResponse(request InterceptedHtlc, case InterceptorActionResume: rpcResp.Action = routerrpc.ResolveHoldForwardAction_RESUME + case InterceptorActionResumeModified: + //nolint:lll + rpcResp.Action = routerrpc.ResolveHoldForwardAction_RESUME_MODIFIED + + rpcResp.InAmountMsat = uint64(response.IncomingAmount) + rpcResp.OutAmountMsat = uint64(response.OutgoingAmount) + rpcResp.OutWireCustomRecords = response.CustomRecords + default: return nil, fmt.Errorf("unknown action: %v", response.Action) } From 78dde32aeab29c78aa849d33ae6c86ed8358d662 Mon Sep 17 00:00:00 2001 From: ffranr Date: Wed, 18 Sep 2024 15:15:58 +0200 Subject: [PATCH 05/11] invoices: add invoice HTLC interceptor --- invoices_client.go | 202 ++++++++++++++++++++++++++++++++++++++ testdata/permissions.json | 8 ++ 2 files changed, 210 insertions(+) diff --git a/invoices_client.go b/invoices_client.go index b44af5a4..51f7aa2d 100644 --- a/invoices_client.go +++ b/invoices_client.go @@ -12,9 +12,55 @@ import ( "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/invoicesrpc" "github.com/lightningnetwork/lnd/lntypes" + "github.com/lightningnetwork/lnd/lnwire" "google.golang.org/grpc" ) +// InvoiceHtlcModifyRequest is a request to modify an HTLC that is attempting to +// settle an invoice. +type InvoiceHtlcModifyRequest struct { + // Invoice is the current state of the invoice, _before_ this HTLC is + // applied. Any HTLC in the invoice is a previously accepted/settled + // one. + Invoice *lnrpc.Invoice + + // CircuitKey is the circuit key of the HTLC that is attempting to + // settle the invoice. + CircuitKey invpkg.CircuitKey + + // ExitHtlcAmt is the amount of the HTLC that is attempting to settle + // the invoice. + ExitHtlcAmt lnwire.MilliSatoshi + + // ExitHtlcExpiry is the expiry of the HTLC that is attempting to settle + // the invoice. + ExitHtlcExpiry uint32 + + // CurrentHeight is the current block height. + CurrentHeight uint32 + + // WireCustomRecords is the wire custom records of the HTLC that is + // attempting to settle the invoice. + WireCustomRecords lnwire.CustomRecords +} + +// InvoiceHtlcModifyResponse is a response to an HTLC modification request. +type InvoiceHtlcModifyResponse struct { + // CircuitKey is the circuit key the response is for. + CircuitKey invpkg.CircuitKey + + // AmtPaid is the amount the HTLC contributes toward settling the + // invoice. This amount can be different from the on-chain amount of the + // HTLC in case of custom channels. To not modify the amount and use the + // on-chain amount, set this to 0. + AmtPaid lnwire.MilliSatoshi +} + +// InvoiceHtlcModifyHandler is a function that handles an HTLC modification +// request. +type InvoiceHtlcModifyHandler func(context.Context, + InvoiceHtlcModifyRequest) (*InvoiceHtlcModifyResponse, error) + // InvoicesClient exposes invoice functionality. type InvoicesClient interface { SubscribeSingleInvoice(ctx context.Context, hash lntypes.Hash) ( @@ -26,6 +72,14 @@ type InvoicesClient interface { AddHoldInvoice(ctx context.Context, in *invoicesrpc.AddInvoiceData) ( string, error) + + // HtlcModifier is a bidirectional streaming RPC that allows a client to + // intercept and modify the HTLCs that attempt to settle the given + // invoice. The server will send HTLCs of invoices to the client and the + // client can modify some aspects of the HTLC in order to pass the + // invoice acceptance tests. + HtlcModifier(ctx context.Context, + handler InvoiceHtlcModifyHandler) error } // InvoiceUpdate contains a state update for an invoice. @@ -38,6 +92,8 @@ type invoicesClient struct { client invoicesrpc.InvoicesClient invoiceMac serializedMacaroon timeout time.Duration + quitOnce sync.Once + quit chan struct{} wg sync.WaitGroup } @@ -48,10 +104,15 @@ func newInvoicesClient(conn grpc.ClientConnInterface, client: invoicesrpc.NewInvoicesClient(conn), invoiceMac: invoiceMac, timeout: timeout, + quit: make(chan struct{}), } } func (s *invoicesClient) WaitForFinished() { + s.quitOnce.Do(func() { + close(s.quit) + }) + s.wg.Wait() } @@ -184,3 +245,144 @@ func fromRPCInvoiceState(state lnrpc.Invoice_InvoiceState) ( return 0, errors.New("unknown state") } + +// HtlcModifier is a bidirectional streaming RPC that allows a client to +// intercept and modify the HTLCs that attempt to settle the given invoice. The +// server will send HTLCs of invoices to the client and the client can modify +// some aspects of the HTLC in order to pass the invoice acceptance tests. +func (s *invoicesClient) HtlcModifier(ctx context.Context, + handler InvoiceHtlcModifyHandler) error { + + // Create a child context that will be canceled when this function + // exits. We use this context to be able to cancel goroutines when we + // exit on errors, because the parent context won't be canceled in that + // case. + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + stream, err := s.client.HtlcModifier( + s.invoiceMac.WithMacaroonAuth(ctx), + ) + if err != nil { + return err + } + + // Create an error channel that we'll send errors on if any of our + // goroutines fail. We buffer by 1 so that the goroutine doesn't depend + // on the stream being read, and select on context cancellation and + // quit channel so that we do not block in the case where we exit with + // multiple errors. + errChan := make(chan error, 1) + + sendErr := func(err error) { + select { + case errChan <- err: + case <-ctx.Done(): + case <-s.quit: + } + } + + // Start a goroutine that consumes interception requests from lnd and + // sends them into our requests channel for handling. The requests + // channel is not buffered because we expect all requests to be handled + // until this function exits, at which point we expect our context to + // be canceled or quit channel to be closed. + requestChan := make(chan InvoiceHtlcModifyRequest) + s.wg.Add(1) + go func() { + defer s.wg.Done() + + for { + // Do a quick check whether our client context has been + // canceled so that we can exit sooner if needed. + if ctx.Err() != nil { + return + } + + req, err := stream.Recv() + if err != nil { + sendErr(err) + return + } + + wireCustomRecords := req.ExitHtlcWireCustomRecords + interceptReq := InvoiceHtlcModifyRequest{ + Invoice: req.Invoice, + CircuitKey: invpkg.CircuitKey{ + ChanID: lnwire.NewShortChanIDFromInt( + req.ExitHtlcCircuitKey.ChanId, + ), + HtlcID: req.ExitHtlcCircuitKey.HtlcId, + }, + ExitHtlcAmt: lnwire.MilliSatoshi( + req.ExitHtlcAmt, + ), + ExitHtlcExpiry: req.ExitHtlcExpiry, + CurrentHeight: req.CurrentHeight, + WireCustomRecords: wireCustomRecords, + } + + // Try to send our interception request, failing on + // context cancel or router exit. + select { + case requestChan <- interceptReq: + + case <-s.quit: + sendErr(ErrRouterShuttingDown) + return + + case <-ctx.Done(): + sendErr(ctx.Err()) + return + } + } + }() + + for { + select { + case request := <-requestChan: + // Handle requests in a goroutine so that the handler + // provided to this function can be blocking. If we + // get an error, send it into our error channel to + // shut down the interceptor. + s.wg.Add(1) + go func() { + defer s.wg.Done() + + // Get a response from handler, this may block + // for a while. + resp, err := handler(ctx, request) + if err != nil { + sendErr(err) + return + } + + key := resp.CircuitKey + amtPaid := uint64(resp.AmtPaid) + rpcResp := &invoicesrpc.HtlcModifyResponse{ + CircuitKey: &invoicesrpc.CircuitKey{ + ChanId: key.ChanID.ToUint64(), + HtlcId: key.HtlcID, + }, + AmtPaid: &amtPaid, + } + + if err := stream.Send(rpcResp); err != nil { + sendErr(err) + return + } + }() + + // If one of our goroutines fails, exit with the error that + // occurred. + case err := <-errChan: + return err + + case <-s.quit: + return ErrRouterShuttingDown + + case <-ctx.Done(): + return ctx.Err() + } + } +} diff --git a/testdata/permissions.json b/testdata/permissions.json index acbbba75..d385379d 100644 --- a/testdata/permissions.json +++ b/testdata/permissions.json @@ -144,6 +144,14 @@ } ] }, + "/invoicesrpc.Invoices/HtlcModifier": { + "permissions": [ + { + "entity": "invoices", + "action": "write" + } + ] + }, "/lnrpc.Lightning/AbandonChannel": { "permissions": [ { From f4728a865f6f9710a26b45be34af37cf3057e4b1 Mon Sep 17 00:00:00 2001 From: George Tsagkarelis Date: Wed, 18 Sep 2024 15:15:59 +0200 Subject: [PATCH 06/11] lndclient: add remote chan reserve option --- lightning_client.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lightning_client.go b/lightning_client.go index 62f58b69..55731a10 100644 --- a/lightning_client.go +++ b/lightning_client.go @@ -64,6 +64,14 @@ func WithScid() OpenChannelOption { } } +// WithRemoteReserve signals that the channel open should set a remote reserve +// amount. +func WithRemoteReserve(reserve uint64) OpenChannelOption { + return func(r *lnrpc.OpenChannelRequest) { + r.RemoteChanReserveSat = reserve + } +} + // LightningClient exposes base lightning functionality. type LightningClient interface { PayInvoice(ctx context.Context, invoice string, From 33648626f572f15469b42c34169b7189f99612d2 Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Fri, 20 Sep 2024 13:09:18 +0200 Subject: [PATCH 07/11] lndclient: add remote max HTLC option --- lightning_client.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lightning_client.go b/lightning_client.go index 55731a10..1c841e1b 100644 --- a/lightning_client.go +++ b/lightning_client.go @@ -72,6 +72,13 @@ func WithRemoteReserve(reserve uint64) OpenChannelOption { } } +// WithRemoteMaxHtlc limits the number of htlcs the remote party can offer. +func WithRemoteMaxHtlc(maxHtlc uint32) OpenChannelOption { + return func(r *lnrpc.OpenChannelRequest) { + r.RemoteMaxHtlcs = maxHtlc + } +} + // LightningClient exposes base lightning functionality. type LightningClient interface { PayInvoice(ctx context.Context, invoice string, From d7aa4ec6cae5d3355f34e08b1332645af194a9dd Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Wed, 18 Sep 2024 15:16:01 +0200 Subject: [PATCH 08/11] lndclient: expose feature bits for ListPeers resp --- lightning_client.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lightning_client.go b/lightning_client.go index 1c841e1b..ef716571 100644 --- a/lightning_client.go +++ b/lightning_client.go @@ -845,6 +845,9 @@ type Peer struct { // Received is the total amount we have received from this peer. Received btcutil.Amount + + // Features is the set of the features supported by the node. + Features *lnwire.FeatureVector } // ChannelBalance contains information about our channel balances. @@ -3417,6 +3420,18 @@ func (s *lightningClient) ListPeers(ctx context.Context) ([]Peer, pingTime := time.Microsecond * time.Duration(peer.PingTime) + var featureBits []lnwire.FeatureBit + for rpcBit := range peer.Features { + featureBits = append( + featureBits, lnwire.FeatureBit(rpcBit), + ) + } + + peerFeatures := lnwire.NewFeatureVector( + lnwire.NewRawFeatureVector(featureBits...), + lnwire.Features, + ) + peers[i] = Peer{ Pubkey: pk, Address: peer.Address, @@ -3426,6 +3441,7 @@ func (s *lightningClient) ListPeers(ctx context.Context) ([]Peer, PingTime: pingTime, Sent: btcutil.Amount(peer.SatSent), Received: btcutil.Amount(peer.SatRecv), + Features: peerFeatures, } } From 48610c45cc4ddbc7e7566e57dfa878d7dce27075 Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Wed, 18 Sep 2024 15:16:02 +0200 Subject: [PATCH 09/11] state_client: add default timeout --- lnd_services.go | 2 +- state_client.go | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lnd_services.go b/lnd_services.go index 1d634ca9..c1788df8 100644 --- a/lnd_services.go +++ b/lnd_services.go @@ -307,7 +307,7 @@ func NewLndServices(cfg *LndServicesConfig) (*GrpcLndServices, error) { } basicClient := lnrpc.NewLightningClient(conn) - stateClient := newStateClient(conn, readonlyMac) + stateClient := newStateClient(conn, readonlyMac, timeout) versionerClient := newVersionerClient(conn, readonlyMac, timeout) cleanupConn := func() { diff --git a/state_client.go b/state_client.go index 498ecb74..18abe289 100644 --- a/state_client.go +++ b/state_client.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "sync" + "time" "github.com/lightningnetwork/lnd/lnrpc" "google.golang.org/grpc" @@ -90,17 +91,19 @@ func (s WalletState) ReadyForGetInfo() bool { type stateClient struct { client lnrpc.StateClient readonlyMac serializedMacaroon + timeout time.Duration wg sync.WaitGroup } // newStateClient returns a new stateClient. func newStateClient(conn grpc.ClientConnInterface, - readonlyMac serializedMacaroon) *stateClient { + readonlyMac serializedMacaroon, timeout time.Duration) *stateClient { return &stateClient{ client: lnrpc.NewStateClient(conn), readonlyMac: readonlyMac, + timeout: timeout, } } From f3abe61d8515ddc09216f2793dc8a946e27a0912 Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Wed, 18 Sep 2024 15:16:03 +0200 Subject: [PATCH 10/11] multi: add RawClientWithMacAuth to every client --- chainkit_client.go | 15 +++++++++++++++ chainnotifier_client.go | 15 +++++++++++++++ invoices_client.go | 15 +++++++++++++++ lightning_client.go | 15 +++++++++++++++ lnd_services.go | 8 ++++++++ lnd_services_test.go | 10 ++++++++++ macaroon_recipes.go | 11 +++++++++++ router_client.go | 15 +++++++++++++++ signer_client.go | 15 +++++++++++++++ state_client.go | 15 +++++++++++++++ versioner_client.go | 19 +++++++++++++++++-- walletkit_client.go | 13 ++++++++++++- 12 files changed, 163 insertions(+), 3 deletions(-) diff --git a/chainkit_client.go b/chainkit_client.go index 3351ddba..48a0fcd9 100644 --- a/chainkit_client.go +++ b/chainkit_client.go @@ -14,6 +14,8 @@ import ( // ChainKitClient exposes chain functionality. type ChainKitClient interface { + ServiceClient[chainrpc.ChainKitClient] + // GetBlock returns a block given the corresponding block hash. GetBlock(ctx context.Context, hash chainhash.Hash) (*wire.MsgBlock, error) @@ -41,6 +43,10 @@ type chainKitClient struct { wg sync.WaitGroup } +// A compile time check to ensure that chainKitClient implements the +// ChainKitClient interface. +var _ ChainKitClient = (*chainKitClient)(nil) + func newChainKitClient(conn grpc.ClientConnInterface, chainMac serializedMacaroon, timeout time.Duration) *chainKitClient { @@ -55,6 +61,15 @@ func (s *chainKitClient) WaitForFinished() { s.wg.Wait() } +// RawClientWithMacAuth returns a context with the proper macaroon +// authentication, the default RPC timeout, and the raw client. +func (s *chainKitClient) RawClientWithMacAuth( + parentCtx context.Context) (context.Context, time.Duration, + chainrpc.ChainKitClient) { + + return s.chainMac.WithMacaroonAuth(parentCtx), s.timeout, s.client +} + // GetBlock returns a block given the corresponding block hash. func (s *chainKitClient) GetBlock(ctxParent context.Context, hash chainhash.Hash) (*wire.MsgBlock, error) { diff --git a/chainnotifier_client.go b/chainnotifier_client.go index 744303d4..0c7b088a 100644 --- a/chainnotifier_client.go +++ b/chainnotifier_client.go @@ -60,6 +60,8 @@ func WithReOrgChan(reOrgChan chan struct{}) NotifierOption { // ChainNotifierClient exposes base lightning functionality. type ChainNotifierClient interface { + ServiceClient[chainrpc.ChainNotifierClient] + RegisterBlockEpochNtfn(ctx context.Context) ( chan int32, chan error, error) @@ -81,6 +83,10 @@ type chainNotifierClient struct { wg sync.WaitGroup } +// A compile time check to ensure that chainNotifierClient implements the +// ChainNotifierClient interface. +var _ ChainNotifierClient = (*chainNotifierClient)(nil) + func newChainNotifierClient(conn grpc.ClientConnInterface, chainMac serializedMacaroon, timeout time.Duration) *chainNotifierClient { @@ -95,6 +101,15 @@ func (s *chainNotifierClient) WaitForFinished() { s.wg.Wait() } +// RawClientWithMacAuth returns a context with the proper macaroon +// authentication, the default RPC timeout, and the raw client. +func (s *chainNotifierClient) RawClientWithMacAuth( + parentCtx context.Context) (context.Context, time.Duration, + chainrpc.ChainNotifierClient) { + + return s.chainMac.WithMacaroonAuth(parentCtx), s.timeout, s.client +} + func (s *chainNotifierClient) RegisterSpendNtfn(ctx context.Context, outpoint *wire.OutPoint, pkScript []byte, heightHint int32) ( chan *chainntnfs.SpendDetail, chan error, error) { diff --git a/invoices_client.go b/invoices_client.go index 51f7aa2d..4d2940f9 100644 --- a/invoices_client.go +++ b/invoices_client.go @@ -63,6 +63,8 @@ type InvoiceHtlcModifyHandler func(context.Context, // InvoicesClient exposes invoice functionality. type InvoicesClient interface { + ServiceClient[invoicesrpc.InvoicesClient] + SubscribeSingleInvoice(ctx context.Context, hash lntypes.Hash) ( <-chan InvoiceUpdate, <-chan error, error) @@ -97,6 +99,10 @@ type invoicesClient struct { wg sync.WaitGroup } +// A compile time check to ensure that invoicesClient implements the +// InvoicesClient interface. +var _ InvoicesClient = (*invoicesClient)(nil) + func newInvoicesClient(conn grpc.ClientConnInterface, invoiceMac serializedMacaroon, timeout time.Duration) *invoicesClient { @@ -116,6 +122,15 @@ func (s *invoicesClient) WaitForFinished() { s.wg.Wait() } +// RawClientWithMacAuth returns a context with the proper macaroon +// authentication, the default RPC timeout, and the raw client. +func (s *invoicesClient) RawClientWithMacAuth( + parentCtx context.Context) (context.Context, time.Duration, + invoicesrpc.InvoicesClient) { + + return s.invoiceMac.WithMacaroonAuth(parentCtx), s.timeout, s.client +} + func (s *invoicesClient) SettleInvoice(ctx context.Context, preimage lntypes.Preimage) error { diff --git a/lightning_client.go b/lightning_client.go index ef716571..3c3ce061 100644 --- a/lightning_client.go +++ b/lightning_client.go @@ -81,6 +81,8 @@ func WithRemoteMaxHtlc(maxHtlc uint32) OpenChannelOption { // LightningClient exposes base lightning functionality. type LightningClient interface { + ServiceClient[lnrpc.LightningClient] + PayInvoice(ctx context.Context, invoice string, maxFee btcutil.Amount, outgoingChannel *uint64) chan PaymentResult @@ -1330,6 +1332,10 @@ type lightningClient struct { adminMac serializedMacaroon } +// A compile time check to ensure that lightningClient implements the +// LightningClient interface. +var _ LightningClient = (*lightningClient)(nil) + func newLightningClient(conn grpc.ClientConnInterface, timeout time.Duration, params *chaincfg.Params, adminMac serializedMacaroon) *lightningClient { @@ -1353,6 +1359,15 @@ func (s *lightningClient) WaitForFinished() { s.wg.Wait() } +// RawClientWithMacAuth returns a context with the proper macaroon +// authentication, the default RPC timeout, and the raw client. +func (s *lightningClient) RawClientWithMacAuth( + parentCtx context.Context) (context.Context, time.Duration, + lnrpc.LightningClient) { + + return s.adminMac.WithMacaroonAuth(parentCtx), s.timeout, s.client +} + // WalletBalance returns a summary of the node's wallet balance. func (s *lightningClient) WalletBalance(ctx context.Context) ( *WalletBalance, error) { diff --git a/lnd_services.go b/lnd_services.go index c1788df8..7b51e01b 100644 --- a/lnd_services.go +++ b/lnd_services.go @@ -78,6 +78,14 @@ var ( } ) +// ServiceClient is an interface that all lnd service clients need to implement. +type ServiceClient[T any] interface { + // RawClientWithMacAuth returns a context with the proper macaroon + // authentication, the default RPC timeout, and the raw client. + RawClientWithMacAuth(parentCtx context.Context) (context.Context, + time.Duration, T) +} + // LndServicesConfig holds all configuration settings that are needed to connect // to an lnd node. type LndServicesConfig struct { diff --git a/lnd_services_test.go b/lnd_services_test.go index b1f46f8c..21be7631 100644 --- a/lnd_services_test.go +++ b/lnd_services_test.go @@ -4,6 +4,7 @@ import ( "context" "errors" "testing" + "time" "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/verrpc" @@ -18,6 +19,15 @@ type mockVersioner struct { err error } +// RawClientWithMacAuth returns a context with the proper macaroon +// authentication, the default RPC timeout, and the raw client. +func (m *mockVersioner) RawClientWithMacAuth( + parentCtx context.Context) (context.Context, time.Duration, + verrpc.VersionerClient) { + + return parentCtx, 0, nil +} + func (m *mockVersioner) GetVersion(_ context.Context) (*verrpc.Version, error) { return m.version, m.err } diff --git a/macaroon_recipes.go b/macaroon_recipes.go index ed15d463..0afd39da 100644 --- a/macaroon_recipes.go +++ b/macaroon_recipes.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "reflect" + "slices" "strings" ) @@ -43,6 +44,12 @@ var ( "OpenChannelStream": "OpenChannel", "ListSweepsVerbose": "ListSweeps", } + + // ignores is a list of method names on the client implementations that + // we don't need to check macaroon permissions for. + ignores = []string{ + "RawClientWithMacAuth", + } ) // MacaroonRecipe returns a list of macaroon permissions that is required to use @@ -79,6 +86,10 @@ func MacaroonRecipe(c LightningClient, packages []string) ([]MacaroonPermission, methodName = rename } + if slices.Contains(ignores, methodName) { + continue + } + // The full RPC URI is /package.Service/MethodName. rpcURI := fmt.Sprintf( "/%s.%s/%s", pkg, serverName, methodName, diff --git a/router_client.go b/router_client.go index 10164064..77550f14 100644 --- a/router_client.go +++ b/router_client.go @@ -31,6 +31,8 @@ var ErrRouterShuttingDown = errors.New("router shutting down") // RouterClient exposes payment functionality. type RouterClient interface { + ServiceClient[routerrpc.RouterClient] + // SendPayment attempts to route a payment to the final destination. The // call returns a payment update stream and an error stream. SendPayment(ctx context.Context, request SendPaymentRequest) ( @@ -405,6 +407,10 @@ type routerClient struct { wg sync.WaitGroup } +// A compile time check to ensure that routerClient implements the RouterClient +// interface. +var _ RouterClient = (*routerClient)(nil) + func newRouterClient(conn grpc.ClientConnInterface, routerKitMac serializedMacaroon, timeout time.Duration) *routerClient { @@ -426,6 +432,15 @@ func (r *routerClient) WaitForFinished() { r.wg.Wait() } +// RawClientWithMacAuth returns a context with the proper macaroon +// authentication, the default RPC timeout, and the raw client. +func (r *routerClient) RawClientWithMacAuth( + parentCtx context.Context) (context.Context, time.Duration, + routerrpc.RouterClient) { + + return r.routerKitMac.WithMacaroonAuth(parentCtx), r.timeout, r.client +} + // SendPayment attempts to route a payment to the final destination. The call // returns a payment update stream and an error stream. func (r *routerClient) SendPayment(ctx context.Context, diff --git a/signer_client.go b/signer_client.go index 23ccb6b9..7fa0b844 100644 --- a/signer_client.go +++ b/signer_client.go @@ -18,6 +18,8 @@ import ( // SignerClient exposes sign functionality. type SignerClient interface { + ServiceClient[signrpc.SignerClient] + // SignOutputRaw is a method that can be used to generate a signature // for a set of inputs/outputs to a transaction. Each request specifies // details concerning how the outputs should be signed, which keys they @@ -190,6 +192,10 @@ type signerClient struct { timeout time.Duration } +// A compile time check to ensure that signerClient implements the SignerClient +// interface. +var _ SignerClient = (*signerClient)(nil) + func newSignerClient(conn grpc.ClientConnInterface, signerMac serializedMacaroon, timeout time.Duration) *signerClient { @@ -200,6 +206,15 @@ func newSignerClient(conn grpc.ClientConnInterface, } } +// RawClientWithMacAuth returns a context with the proper macaroon +// authentication, the default RPC timeout, and the raw client. +func (s *signerClient) RawClientWithMacAuth( + parentCtx context.Context) (context.Context, time.Duration, + signrpc.SignerClient) { + + return s.signerMac.WithMacaroonAuth(parentCtx), s.timeout, s.client +} + func marshallSignDescriptors( signDescriptors []*SignDescriptor) []*signrpc.SignDescriptor { diff --git a/state_client.go b/state_client.go index 18abe289..ca9d8034 100644 --- a/state_client.go +++ b/state_client.go @@ -12,6 +12,8 @@ import ( // StateClient exposes base lightning functionality. type StateClient interface { + ServiceClient[lnrpc.StateClient] + // SubscribeState subscribes to the current state of the wallet. SubscribeState(ctx context.Context) (chan WalletState, chan error, error) @@ -96,6 +98,10 @@ type stateClient struct { wg sync.WaitGroup } +// A compile time check to ensure that stateClient implements the StateClient +// interface. +var _ StateClient = (*stateClient)(nil) + // newStateClient returns a new stateClient. func newStateClient(conn grpc.ClientConnInterface, readonlyMac serializedMacaroon, timeout time.Duration) *stateClient { @@ -112,6 +118,15 @@ func (s *stateClient) WaitForFinished() { s.wg.Wait() } +// RawClientWithMacAuth returns a context with the proper macaroon +// authentication, the default RPC timeout, and the raw client. +func (s *stateClient) RawClientWithMacAuth( + parentCtx context.Context) (context.Context, time.Duration, + lnrpc.StateClient) { + + return s.readonlyMac.WithMacaroonAuth(parentCtx), s.timeout, s.client +} + // SubscribeState subscribes to the current state of the wallet. func (s *stateClient) SubscribeState(ctx context.Context) (chan WalletState, chan error, error) { diff --git a/versioner_client.go b/versioner_client.go index 08320dd3..1de9de09 100644 --- a/versioner_client.go +++ b/versioner_client.go @@ -12,6 +12,8 @@ import ( // VersionerClient exposes the version of lnd. type VersionerClient interface { + ServiceClient[verrpc.VersionerClient] + // GetVersion returns the version and build information of the lnd // daemon. GetVersion(ctx context.Context) (*verrpc.Version, error) @@ -23,6 +25,10 @@ type versionerClient struct { timeout time.Duration } +// A compile time check to ensure that versionerClient implements the +// VersionerClient interface. +var _ VersionerClient = (*versionerClient)(nil) + func newVersionerClient(conn grpc.ClientConnInterface, readonlyMac serializedMacaroon, timeout time.Duration) *versionerClient { @@ -33,6 +39,15 @@ func newVersionerClient(conn grpc.ClientConnInterface, } } +// RawClientWithMacAuth returns a context with the proper macaroon +// authentication, the default RPC timeout, and the raw client. +func (v *versionerClient) RawClientWithMacAuth( + parentCtx context.Context) (context.Context, time.Duration, + verrpc.VersionerClient) { + + return v.readonlyMac.WithMacaroonAuth(parentCtx), v.timeout, v.client +} + // GetVersion returns the version and build information of the lnd // daemon. // @@ -47,7 +62,7 @@ func (v *versionerClient) GetVersion(ctx context.Context) (*verrpc.Version, return v.client.GetVersion(rpcCtx, &verrpc.VersionRequest{}) } -// VersionString returns a nice, human readable string of a version returned by +// VersionString returns a nice, human-readable string of a version returned by // the VersionerClient, including all build tags. func VersionString(version *verrpc.Version) string { short := VersionStringShort(version) @@ -55,7 +70,7 @@ func VersionString(version *verrpc.Version) string { return fmt.Sprintf("%s, build tags '%s'", short, enabledTags) } -// VersionStringShort returns a nice, human readable string of a version +// VersionStringShort returns a nice, human-readable string of a version // returned by the VersionerClient. func VersionStringShort(version *verrpc.Version) string { versionStr := fmt.Sprintf( diff --git a/walletkit_client.go b/walletkit_client.go index 9fdb2cce..99174f89 100644 --- a/walletkit_client.go +++ b/walletkit_client.go @@ -66,6 +66,8 @@ func WithUnspentUnconfirmedOnly() ListUnspentOption { // WalletKitClient exposes wallet functionality. type WalletKitClient interface { + ServiceClient[walletrpc.WalletKitClient] + // ListUnspent returns a list of all utxos spendable by the wallet with // a number of confirmations between the specified minimum and maximum. ListUnspent(ctx context.Context, minConfs, maxConfs int32, @@ -214,7 +216,7 @@ type walletKitClient struct { params *chaincfg.Params } -// A compile-time constraint to ensure walletKitclient satisfies the +// A compile time check to ensure that walletKitClient implements the // WalletKitClient interface. var _ WalletKitClient = (*walletKitClient)(nil) @@ -230,6 +232,15 @@ func newWalletKitClient(conn grpc.ClientConnInterface, } } +// RawClientWithMacAuth returns a context with the proper macaroon +// authentication, the default RPC timeout, and the raw client. +func (m *walletKitClient) RawClientWithMacAuth( + parentCtx context.Context) (context.Context, time.Duration, + walletrpc.WalletKitClient) { + + return m.walletKitMac.WithMacaroonAuth(parentCtx), m.timeout, m.client +} + // ListUnspent returns a list of all utxos spendable by the wallet with a number // of confirmations between the specified minimum and maximum. func (m *walletKitClient) ListUnspent(ctx context.Context, minConfs, From ac3012686ab52f2c34b0f71e1da231410a54a1df Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Wed, 18 Sep 2024 15:28:44 +0200 Subject: [PATCH 11/11] lnd_services: bump minimum required lnd version to v0.18.4-beta With the latest lnd master versioned as v0.18.99-beta, we can now require this commit of lndclient to require a minimum version of v0.18.4-beta (which will ship all the RPC changes in this PR). --- lnd_services.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lnd_services.go b/lnd_services.go index 7b51e01b..835c83fc 100644 --- a/lnd_services.go +++ b/lnd_services.go @@ -37,11 +37,11 @@ var ( // required in lnd to get all functionality implemented in lndclient. // Users can provide their own, specific version if needed. If only a // subset of the lndclient functionality is needed, the required build - // tags can be adjusted accordingly. This default will be used as a fall - // back version if none is specified in the configuration. + // tags can be adjusted accordingly. This default will be used as a + // fallback version if none is specified in the configuration. minimalCompatibleVersion = &verrpc.Version{ AppMajor: 0, - AppMinor: 17, + AppMinor: 18, AppPatch: 4, BuildTags: DefaultBuildTags, }