Skip to content

lnd: only init wallet with root key if supported#799

Open
ekzyis wants to merge 2 commits into
bitcoin-dev-project:mainfrom
ekzyis:lnd-pod-overridable-startupProbe
Open

lnd: only init wallet with root key if supported#799
ekzyis wants to merge 2 commits into
bitcoin-dev-project:mainfrom
ekzyis:lnd-pod-overridable-startupProbe

Conversation

@ekzyis
Copy link
Copy Markdown
Contributor

@ekzyis ekzyis commented Mar 11, 2026

This makes it possible to override startupProbe of an LND node.

This is required for bitcoin-dev-project/wrath-of-nalo#8 because lnd v0.15.5-beta does not support macaroon_root_key in initwallet. (Support was added in v0.16.0, see lightningnetwork/lnd#6457.

I couldn't simply use {{- toYaml .Values.startupProbe | nindent 8 }} and put the current default value into values.yaml similar to livenessProbe etc. because {{ .Values.global.chain }} wouldn't get interpolated.

This was tested by deploying the battlefield in bitcoin-dev-project/wrath-of-nalo#8 and inspecting the pod running lnd v0.15.5-beta.

Instead of the above, it now parses the version, see #799 (comment).

@ekzyis ekzyis marked this pull request as draft March 11, 2026 18:02
@pinheadmz
Copy link
Copy Markdown
Contributor

Instead of replacing the entire startup probe, can we add a flag (or even better, actual version parsing like this) and just leave out the macaroon root key option?

What happens if the option is still left in, does lnd 15 refuse to start?

I think the macaroon root key logic is mainly for friendly experimentation, and isn't used in battle games where each node has to have security from players, so I think this is generally an ok thing to do.

@ekzyis
Copy link
Copy Markdown
Contributor Author

ekzyis commented May 7, 2026

Instead of replacing the entire startup probe, can we add a flag (or even better, actual version parsing like this) and just leave out the macaroon root key option?

Sounds good, I'll look into this, thanks!

What happens if the option is still left in, does lnd 15 refuse to start?

The LND node starts, but it will wait forever for the wallet:

$ kubectl get pods
NAME           READY   STATUS    RESTARTS      AGE
aries-lnd      1/1     Running   0             21m
aries-lnd-ln   0/1     Running   0             21m
miner          1/1     Running   0             21m
miner-ln       3/3     Running   2 (19m ago)   21m
$ kubectl logs aries-lnd-ln | tail -1
2026-05-07 12:09:28.534 [INF] LTND: Waiting for wallet encryption password. Use `lncli create` to create a wallet, `lncli unlock` to unlock an existing wallet, or `lncli changepassword` to change the password of an existing wallet and unlock it.

because startupProbe times out:

$ kubectl describe pod aries-lnd-ln
...
Events:
  Type     Reason     Age                  From               Message
  ----     ------     ----                 ----               -------
  Normal   Scheduled  14m                  default-scheduler  Successfully assigned default/aries-lnd-ln to minikube
  Normal   Pulling    14m                  kubelet            Pulling image "lightninglabs/lnd:v0.15.5-beta"
  Normal   Pulled     14m                  kubelet            Successfully pulled image "lightninglabs/lnd:v0.15.5-beta" in 4.3s (15.665s including waiting). Image size: 101225027 bytes.
  Normal   Created    14m                  kubelet            Created container: lnd
  Normal   Started    14m                  kubelet            Started container lnd
  Warning  Unhealthy  4m9s (x2 over 9m9s)  kubelet            Startup probe failed: command timed out: "/bin/sh -c MACAROON_PATH=\"/root/.lnd/data/chain/bitcoin/regtest/admin.macaroon\"\n\n# If wallet is already initialized, unlock it and
exit\nif [ -f \"$MACAROON_PATH\" ]; then\n  until [ \"$(curl --silent --insecure https://localhost:8080/v1/unlockwallet --data \"{\\\"wallet_password\\\":\\\"AAAAAAAAAAA=\\\"}\")\" == \"{}\" ]; do\n    sleep 5\n  done\n  exit 0\nfi\n\nuntil curl --silent --insecure https://localhost:8080/v1/genseed > /tmp/genseed.json; do\n  sleep 5\ndone\n\nPHRASE=$(cat /tmp/genseed.json | grep -o '\\[[^]]*\\]')\n\nuntil curl --fail --insecure https://localhost:8080/v1/initwallet --data \"{\\\"macaroon_root_key\\\":\\\"IFwE0Bhza6cC+ZsnZsinpcdExoRO3D1PZH6adjXPlBM=\\\", \\\"wallet_password\\\":\\\"AAAAAAAAAAA=\\\", \\\"cipher_seed_mnemonic\\\": $PHRASE}\"; do\n  sleep 5\ndone\n" timed out after 5m0s

because this loop runs forever:

until curl --fail --insecure https://localhost:8080/v1/initwallet --data "{\"macaroon_root_key\":\"{{ .Values.macaroonRootKey }}\", \"wallet_password\":\"AAAAAAAAAAA=\", \"cipher_seed_mnemonic\": $PHRASE}"; do
  sleep 5
done

(At least I'm pretty sure that's what's happening. k8s doesn't seem to expose the output of startupProbe.)


Edit: Could be that I misunderstood what you meant with "What happens if the option is still left in". Maybe you didn't mean what currently happens (macaroon_root_key as part of /initwallet), but what would happen after your suggestion was implemented, and macaroonRootKey is still part of the pod YAML config. Will check!

@ekzyis ekzyis force-pushed the lnd-pod-overridable-startupProbe branch from d8bf25e to 5efdcc6 Compare May 7, 2026 16:40
@ekzyis ekzyis changed the title Make lnd.startupProbe overridable lnd: only init wallet with root key if supported May 7, 2026
@ekzyis
Copy link
Copy Markdown
Contributor Author

ekzyis commented May 7, 2026

(or even better, actual version parsing like this)

5efdcc6 now does this, and it's much better!

What happens if the option is still left in, does lnd 15 refuse to start?

It now doesn't matter if lnd.macaroonRootKey is set or not for lnd<0.16.0-beta, it won't be used.

I have tested this like this:

$ pip install -e .
$ warnet setup
...
$ warnet deploy battlefields/regtest_fake_channel_dos/
$ kubectl get pods
NAME           READY   STATUS    RESTARTS        AGE
aries-lnd      1/1     Running   0               2m40s
aries-lnd-ln   1/1     Running   0               2m40s
miner          1/1     Running   0               2m40s
miner-ln       3/3     Running   4 (2m11s ago)   2m40s
$ kubectl describe pods | grep initwallet
until curl --fail --insecure https://localhost:8080/v1/initwallet --data "{\"wallet_password\":\"AAAAAAAAAAA=\", \"cipher_seed_mnemonic\": $PHRASE}"; do
until curl --fail --insecure https://localhost:8080/v1/initwallet --data "{\"macaroon_root_key\":\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\", \"wallet_password\":\"AAAAAAAAAAA=\", \"cipher_seed_mnemonic\": $PHRASE}"; do
$ kubectl logs aries-lnd-ln | grep wallet
2026-05-07 16:46:49.160 [INF] LTND: Waiting for wallet encryption password. Use `lncli create` to create a wallet, `lncli unlock` to unlock an existing wallet, or `lncli changepassword` to change the password of an existing wallet and unlock it.
2026-05-07 16:46:55.217 [INF] LNWL: Opened wallet
2026-05-07 16:46:55.655 [INF] LNWL: The wallet has been unlocked without a time limit
2026-05-07 16:46:55.682 [INF] WLKT: Baking macaroons for WalletKit RPC Server at: /root/.lnd/data/chain/bitcoin/regtest/walletkit.macaroon

(The miner-ln pod is running v0.20.1-beta.)

@ekzyis ekzyis marked this pull request as ready for review May 7, 2026 16:59
Comment thread resources/charts/bitcoincore/charts/lnd/templates/_helpers.tpl
@ekzyis ekzyis marked this pull request as draft May 18, 2026 13:08
@ekzyis ekzyis force-pushed the lnd-pod-overridable-startupProbe branch 3 times, most recently from d76732c to 56334d2 Compare May 18, 2026 17:24
@ekzyis
Copy link
Copy Markdown
Contributor Author

ekzyis commented May 18, 2026

It'd be great if you could add a 0.15.5 node in one of the tests so we can see this work in CI

Done in 56334d2. Included the node in test_admin_macaroons.

During network setup, wallet addresses are fetched to fund the node. I had to read admin.macaroon from the pod to pass RPC authentication.

Since reading admin.macaroon requires permission to execute code on the pod, any scenario that includes a pre-16 lnd node now needs to be run as admin, which is why I added --admin to the pyln_connect scenario.

I don't like this, but short of some hack to make pre-16 lnd support custom macaroon root keys, like writing macaroons.db with the root key material manually, or somehow wiring the return value of initwallet back into the pod config (both ideas sound crazy), I don't see how we could pass RPC auth without reading admin.macaroon.

Comment thread resources/scenarios/commander.py Outdated
Comment thread test/ln_basic_test.py Outdated
This includes a lnd v0.15.5-beta node in the existing macaroon tests.

To set the correct Grpc-Metadata-macaroon RPC header, we read admin.macaroon
from the pod if the version is below v0.16.0-beta. RBAC was updated for that.
@ekzyis ekzyis force-pushed the lnd-pod-overridable-startupProbe branch from 56334d2 to 32db780 Compare May 18, 2026 21:01
@ekzyis ekzyis marked this pull request as ready for review May 18, 2026 21:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants