@hackage btc-lsp0.1.0.0

Lightning service provider

btc-lsp

Bitcoin Lightning Service Provider. Development environment is packed into nix-shell.

Auth

Every btc-lsp gRPC request/response does have ctx (context) field in payload which contains credentials:

  • First is nonce. The nonce is used for security reasons and is used to guard against replay attacks. The server will reject any request that comes with an incorrect nonce. The only requirement for the nonce is that it needs to be strictly increasing. Nonce generation is often achieved by using the current UNIX timestamp.
  • Second is ln_pub_key. This is lightning node network identity public key in DER format. This key is used to verify request/response signature from headers/trailers.

Also, every request/response does have a signature which is:

  • Signed with LN identity key (key locator family is 6 and index is 0).
  • Signed over binary request payload in exact gRPC/http2 wire format (1 byte of compression flag + 4 bytes of payload length in big endian format + payload bytes).
  • Single hashed (double_hash parameter is False).
  • Not compact (compact_sig parameter is False).
  • Using DER binary format.
  • Base64-encoded according official http2 spec.
  • Located in sig-bin gRPC header/trailer.

Haskell/Nix

Spawn shell:

# If you have Nix installed (a bit faster)
./nix/hm-shell-native.sh

# If you have Docker installed (works on Mac)
./nix/hm-shell-docker.sh

Work with Haskell sources in shell:

vi .

Run tests with hot code reloading:

./nix/ns-ghcid-test.sh

Run app with hot code reloading:

./nix/ns-ghcid-main.sh

Release

Releases are automated by CI. To create new release, bump the version inside VERSION file. Then push all changes into github and merge into master branch. Then run:

../nix/hm-release.sh

The script will push new tag which will trigger new github release and package.

Kubernetes

Some tools are required to be installed directly on host machine. They can be installed using nix-env:

./nix/nix-install-tools.sh

If nix is not available, install tools in any other way you like:

expect-5.45.4
jq-1.6
kubectl-1.23.5
minikube-1.25.2
wget-1.21.3
helm-3.8.2

Regtest setup

  1. Setup minikube cluster and deploy k8s resources:
./nix/mk-deploy-regtest.sh
  1. Forward services to host network:
./nix/k8s-forward.sh

Service/config upgrade

  1. Set k8s context to upgrade
kubectl config use-context <ctx-name>
  1. Upgrade services/configs
./nix/k8s-upgrade.sh <net> <mode> <services>

Example

./nix/k8s-upgrade.sh --regtest --prebuilt lsp bitcoind

Deploy testnet (DigitalOcean)

  1. Install doctl

If you have used nix-env doctl will already be installed, otherwise install it manually.

doctl-1.71.1
  1. Configure doctl

Follow the guide below to configure doctl.

https://docs.digitalocean.com/reference/doctl/how-to/install/

  1. Setup Managed Kubernetes, Managed Postgres, DNS records, TLS certificates and deploy k8s resources:
./nix/do-deploy-testnet.sh

Destroy testnet (DigitalOcean)

./nix/do-destroy-testnet.sh

Deploy testnet (AWS)

  1. Install aws cli, eksctl and helm:

If you have used nix-env everything will be already installed, otherwise install manually.

aws-cli-2.5.4
eksctl-0.93.0
helm-3.8.2
  1. Create IAM user with AdministratorAccess in AWS Console

  2. Configure aws cli access_key_id, secret_access_key, region

aws configure
  1. Setup EKS, RDS, Route53, Request certs from ACM and deploy k8s resources:
./nix/aws-deploy-testnet.sh

Destroy testnet (AWS)

./nix/aws-destroy-testnet.sh

Troubleshoot

  1. Get list of running pods:
kubectl get po
  1. Get info about pod:
kubectl describe pod <pod-name>
  1. Get detailed info about current cluster state (regtest only):
minikube dashboard --profile=btc-lsp
  1. Lnd after restart is locked. Usually Lsp unlocks it automatically, but if for some reason it's locked (for example Lsp is not running) then you can unlock it with:
./nix/k8s-lazy-init-unlock.sh
  1. Delete all failed Pods:
kubectl delete pod --all-namespaces --field-selector 'status.phase=Failed'
  1. Connect to existing cluster on DigitalOcean:

Get cluster ID

doctl k cluster get lsp-testnet

Add context to kube config

doctl kubernetes cluster kubeconfig save <cluster-id>
  1. Connect to existing eks cluster on AWS:
aws eks update-kubeconfig --name lsp-testnet
  1. Manage k8s contexts:

Display list of contexts

kubectl config get-contexts

Display the current context

kubectl config current-context

Set current context to btc-lsp

kubectl config use-context btc-lsp
  1. List k8s nodes:
kubectl get nodes -o wide
  1. Get current storage class:
kubectl get storageclass

Seed

Secure lnd seed generation procedure for the mainnet:

  1. Go to a private place without cameras and witnesses.

  2. Create USB stick with minimal nixos image (cli only).

  3. Boot from USB stick to nixos installer and connect to the internet.

  4. Load nix-shell using the command:

nix-shell --pure -p '(import (fetchTarball { url = "https://github.com/coingaming/src/tarball/ef7ed491e5102063763538bc4cb2e86bc8021973"; sha256 = "1ml6jrz605jx7pmzd38d1490n8cbjv8yaclpqy57j7lqp1raaa7w"; } + "/nix/project.nix")).nixBitcoin.lndinit'
  1. DISCONNECT FROM THE INTERNET.

  2. Generate the seed using the command:

lndinit gen-seed
  1. Copy the seed to non-digital durable media, for example steel plate.

  2. Turn off the computer and erase the USB stick.

  3. Keep the seed media safe.