Lightning Implementation in Electrum

Thomas Voegtlin

PGP: 6694 D8DE 7BE8 EE56 31BE D950 2BD5 824B 7F94 70E6


Presenter Notes

Light clients are needed

  • Bitcoin's security depends on the bitcoin price.
  • The price requires a large userbase.

Our goal: make light clients as safe as possible

  • Compete with custodian or non-custodian websites.
  • Same user experience, without the risks

Presenter Notes

Electrum (since 2011)

  • You own the keys.
  • Safe: Deterministic
  • Fast and light: Client-server architecture
  • Do not trust, verify: SPV

what made the success of Electrum is the ability to restore from seed

Presenter Notes

Lightning wallets

New constraints:

  • Cannot restore from seed.
  • Routing, liquidity
  • You need to watch your channels
  • You need to be online to receive payments

Custodian services:

  • will take care of backups
  • will take care of liquidity
  • will watch your channels
  • receiver can be offline

show vascular image

not saying it's bad, but bitcoin cannot exist if all users use these types of services. it makes bitcoin unstable, the consequence of hacks are bigger

Presenter Notes

Lightning in Electrum

  • Development started 1 year ago.
  • Python implementation
  • Will be merged soon (tm)

Presenter Notes

Lightning in Electrum

gui, cli, passes tests

Presenter Notes

Demo 1: Send and Receive

Setup regtest node: bitcoind + lnd + ElectrumX

1 $bitcoin_cli generatetoaddress 1 $($bitcoin_cli getnewaddress)
2 $lncli getinfo

Checkout lightning branch of Electrum

1 git clone [email protected]:spesmilo/electrum.git
2 cd electrum
3 git checkout lightning


1 alice="./run_electrum --regtest --lightning -D /tmp/alice"
2 $alice create
3 $bitcoin_cli sendtoaddress $($alice getunusedaddress) 1
4 $alice --server


1 bob="./run_electrum --regtest --lightning -D /tmp/bob"
2 $bob create
3 $bitcoin_cli sendtoaddress $($bob getunusedaddress) 1
4 $bob --server

alice opens channel, pays bob.

lightning dialog, closure, force closure

Presenter Notes

Redeeming CTX outputs

Our latest CTX

- to_local : after CSV
- to_remote : for them
- sent HTLCs : htlctx -> after CSV
- received HTLCs : if preimage then htlctx -> after CSV

Their latest CTX

- to_local : for them
- to_remote : for us
- sent HTLCs  : we need preimagee
- received HTLCs : after CLTV

Their breach CTX

- to_local : before CSV
- to_remote : for us
- sent HTLCs:
    - unspent : for us
    - spent : before CSV
- received HTLCs:
    - unspent : for us
    - spent : before CSV

Presenter Notes

Simple Payment Verification (SPV)

  • Server cannot fake payments (proof of correctness)

  • Server can lie by omission (no proof of completeness)

Presenter Notes


  • Proof of completeness is not enough
  • We cannot expect users to watch their channels
  • Delegate breach remedy to 3rd party

Presenter Notes

Watchtower: models and incentives

Public/Anonymous WT

  • Does not know who you are until there is a breach
  • Must store data forever, or pretend to do so
  • Can be paid on breach, or using anonymous tokens

Private WT

  • Knows about your channels
  • can delete data
  • Could charge a monthly subscription

Presenter Notes

Electrum Watchtower

  • Use presigned transactions
  • Redeem CSV outputs
  • Can be local or remote

Local WT:

  • runs as part of your client or daemon
  • does not need your wallet

Remote WT

  • mirrors local WT
  • same code base

Presenter Notes

Demo 2: Watchtower

Setup Alice, Bob, Carol:

1 rm -rf /tmp/alice/ /tmp/bob/ /tmp/carol
2 $alice create > /dev/null
3 $bob create > /dev/null
4 $carol create > /dev/null

Bob is a listening node

1 $bob setconfig lightning_listen localhost:9735

Carol is a watchtower

1 $carol setconfig watchtower_host
2 $carol setconfig watchtower_port 12345

Alice configures watchtower and gets some funds:

1 $alice setconfig watchtower_url
2 $bitcoin_cli sendtoaddress $($alice getunusedaddress) 1

Presenter Notes

Start daemons

1 $alice daemon start --server
2 $alice daemon load_wallet
3 $bob daemon start --server
4 $bob daemon load_wallet
6 $carol daemon --server -v

Presenter Notes

Alice opens channel with Bob

1 bob_node=$($bob nodeid)
2 $alice open_channel $bob_node 0.15
3 # mine a few blocks
4 $bitcoin_cli generatetoaddress 3 $($bitcoin_cli getnewaddress)

Alice pays Bob

1 request=$($bob addinvoice 0.05 "test")
2 $alice lnpay $request

Presenter Notes

Bob breaches

Bob saves CTX

1 channel=$($bob list_channels|jq '.[] | .channel_point' | tr -d '"')
2 ctx=$($bob get_channel_ctx $channel | jq '.hex' | tr -d '"')

Bob pays Alice

1 request=$($alice addinvoice 0.03 "test2")
2 $bob lnpay $request

Alice goes offline, bob broadcasts old ctx

1 $alice daemon stop
2 $bitcoin_cli sendrawtransaction $ctx

Presenter Notes

Upcoming Releases

Initial release (no ETA):

  • Disable listening/forwarding
  • Enabled through command-line option
  • Users should run their own watchtower

Later release:

  • Enabled in binaries
  • WT service

Presenter Notes

Proof of completeness

With soft fork (might never happen):

  • UTXO set commitment
  • BIP 158 filter commitment

Without soft fork (assume 1 node is honest)

  • Query multiple servers and SPV
  • Neutrino (BIP157 + BIP158)
  • UTXO set with proof of transition

Presenter Notes

Client-side block filtering

aka BIP 157, 158

  • Full nodes build a filter for each block
  • client requests filters, downloads blocks that match
  • if two nodes disagree, binary search and download the block

Presenter Notes

UTXO Merkle tree

  • commitments [soft fork]
  • Merkle tree of the UTXO set
  • root hash commited to blocks

Verifiable transifions

  • UTXO set hash, not commited to blocks
  • Client can request proof of transitions between blocks
  • If nodes disagree, binary search

Presenter Notes