Skip to content

Commit

Permalink
lwk: add TLS support for Electrum
Browse files Browse the repository at this point in the history
Add TLS support for Electrum.
In default, the scheme is a tls connection,
which allows connection to electrs.
context timeout for wallet operations to enhance reliability.
  • Loading branch information
YusukeShimizu committed May 11, 2024
1 parent 103c4f5 commit b72e410
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 20 deletions.
26 changes: 19 additions & 7 deletions cmd/peerswap-plugin/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"context"
"crypto/tls"
"errors"
"fmt"
glog "log"
Expand Down Expand Up @@ -209,22 +210,33 @@ func run(ctx context.Context, lightningPlugin *clightning.ClightningClient) erro
log.Infof("Liquid swaps enabled")
} else if config.LWK != nil && config.LWK.Enabled() {
liquidEnabled = true
ec, err2 := electrum.NewClientTCP(ctx, config.LWK.GetElectrumEndpoint())
if err2 != nil {
return err2
var ec *electrum.Client
if config.LWK.IsElectrumWithTLS() {
ec, err = electrum.NewClientSSL(ctx, config.LWK.GetElectrumEndpoint(), &tls.Config{
MinVersion: tls.VersionTLS12,
})
if err != nil {
return err
}
} else {
ec, err = electrum.NewClientTCP(ctx, config.LWK.GetElectrumEndpoint())
if err != nil {
return err
}
}
liquidRpcWallet, err2 = lwk.NewLWKRpcWallet(lwk.NewLwk(config.LWK.GetLWKEndpoint()),
liquidRpcWallet, err = lwk.NewLWKRpcWallet(lwk.NewLwk(config.LWK.GetLWKEndpoint()),
ec, config.LWK.GetWalletName(), config.LWK.GetSignerName())
if err2 != nil {
return err2
if err != nil {
return err
}
liquidTxWatcher, err = lwk.NewElectrumTxWatcher(ec)
if err != nil {
return err
}
liquidOnChainService = onchain.NewLiquidOnChain(liquidRpcWallet, config.LWK.GetChain())
supportedAssets = append(supportedAssets, "lbtc")
log.Infof("Liquid swaps enabled")
log.Infof("Liquid swaps enabled with LWK. Network: %s, wallet: %s",
config.LWK.GetNetwork(), config.LWK.GetWalletName())
} else {
log.Infof("Liquid swaps disabled")
}
Expand Down
18 changes: 14 additions & 4 deletions cmd/peerswaplnd/peerswapd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"context"
"crypto/tls"
"errors"
"fmt"
"io"
Expand Down Expand Up @@ -231,11 +232,20 @@ func run() error {
liquidOnChainService = onchain.NewLiquidOnChain(liquidRpcWallet, liquidChain)
} else if cfg.LWKConfig.Enabled() {
log.Infof("Liquid swaps enabled with LWK. Network: %s, wallet: %s", cfg.LWKConfig.GetNetwork(), cfg.LWKConfig.GetWalletName())
ec, err := electrum.NewClientTCP(ctx, cfg.LWKConfig.GetElectrumEndpoint())
if err != nil {
return err
var ec *electrum.Client
if cfg.LWKConfig.IsElectrumWithTLS() {
ec, err = electrum.NewClientSSL(ctx, cfg.LWKConfig.GetElectrumEndpoint(), &tls.Config{
MinVersion: tls.VersionTLS12,
})
if err != nil {
return err
}
} else {
ec, err = electrum.NewClientTCP(ctx, cfg.LWKConfig.GetElectrumEndpoint())
if err != nil {
return err
}
}

// This call is blocking, waiting for elements to come alive and sync.
liquidRpcWallet, err = lwk.NewLWKRpcWallet(lwk.NewLwk(cfg.LWKConfig.GetLWKEndpoint()),
ec, cfg.LWKConfig.GetWalletName(), cfg.LWKConfig.GetSignerName())
Expand Down
4 changes: 2 additions & 2 deletions lwk/conf_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ func (b *confBuilder) DefaultConf() (*confBuilder, error) {
switch b.network {
case NetworkTestnet:
lwkEndpoint = "http://localhost:32111"
electrumEndpoint = "tcp://blockstream.info:465"
electrumEndpoint = "ssl://blockstream.info:465"
case NetworkRegtest:
lwkEndpoint = "http://localhost:32112"
electrumEndpoint = "tcp://localhost:60401"
default:
// mainnet is the default port
lwkEndpoint = "http://localhost:32110"
electrumEndpoint = "tcp://blockstream.info:995"
electrumEndpoint = "ssl://blockstream.info:995"
}
lwkURL, err := NewConfURL(lwkEndpoint)
if err != nil {
Expand Down
4 changes: 4 additions & 0 deletions lwk/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ func (c *Conf) GetElectrumEndpoint() string {
return c.electrumEndpoint.Host
}

func (c *Conf) IsElectrumWithTLS() bool {
return c.electrumEndpoint.Scheme == "ssl"
}

func (c *Conf) GetNetwork() string {
return c.network.String()
}
Expand Down
27 changes: 20 additions & 7 deletions lwk/lwkwallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"log"
"math"
"strings"
"time"

"github.com/checksum0/go-electrum/electrum"

Expand All @@ -24,6 +25,10 @@ const (
minimumSatPerByte SatPerKVByte = 0.1
// 1 kb = 1000 bytes
kb float64 = 1000
// TODO: Basically, the inherited ctx should be used
// and there is no need to specify a timeout here.
// Set up here because ctx is not inherited throughout the current codebase.
defaultContextTimeout = time.Second * 5
)

// LWKRpcWallet uses the elementsd rpc wallet
Expand All @@ -47,7 +52,9 @@ func NewLWKRpcWallet(lwkClient *lwkclient, electrumClient *electrum.Client, wall
lwkClient: lwkClient,
electrumClient: electrumClient,
}
err := rpcWallet.setupWallet(context.Background())
ctx, cancel := context.WithTimeout(context.Background(), defaultContextTimeout)
defer cancel()
err := rpcWallet.setupWallet(ctx)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -111,7 +118,8 @@ func (r *LWKRpcWallet) createWallet(ctx context.Context, walletName, signerName
// CreateFundedTransaction takes a tx with outputs and adds inputs in order to spend the tx
func (r *LWKRpcWallet) CreateAndBroadcastTransaction(swapParams *swap.OpeningParams,
asset []byte) (txid, rawTx string, fee Satoshi, err error) {
ctx := context.Background()
ctx, cancel := context.WithTimeout(context.Background(), defaultContextTimeout)
defer cancel()
feerate := float64(r.getFeePerKb(ctx)) * kb
fundedTx, err := r.lwkClient.send(ctx, &sendRequest{
Addressees: []*unvalidatedAddressee{
Expand Down Expand Up @@ -149,7 +157,8 @@ func (r *LWKRpcWallet) CreateAndBroadcastTransaction(swapParams *swap.OpeningPar

// GetBalance returns the balance in sats
func (r *LWKRpcWallet) GetBalance() (Satoshi, error) {
ctx := context.Background()
ctx, cancel := context.WithTimeout(context.Background(), defaultContextTimeout)
defer cancel()
balance, err := r.lwkClient.balance(ctx, &balanceRequest{
WalletName: r.walletName,
})
Expand All @@ -161,7 +170,8 @@ func (r *LWKRpcWallet) GetBalance() (Satoshi, error) {

// GetAddress returns a new blech32 address
func (r *LWKRpcWallet) GetAddress() (string, error) {
ctx := context.Background()
ctx, cancel := context.WithTimeout(context.Background(), defaultContextTimeout)
defer cancel()
address, err := r.lwkClient.address(ctx, &addressRequest{
WalletName: r.walletName})
if err != nil {
Expand All @@ -172,7 +182,8 @@ func (r *LWKRpcWallet) GetAddress() (string, error) {

// SendToAddress sends an amount to an address
func (r *LWKRpcWallet) SendToAddress(address string, amount Satoshi) (string, error) {
ctx := context.Background()
ctx, cancel := context.WithTimeout(context.Background(), defaultContextTimeout)
defer cancel()
sendres, err := r.lwkClient.send(ctx, &sendRequest{
WalletName: r.walletName,
Addressees: []*unvalidatedAddressee{
Expand Down Expand Up @@ -204,7 +215,8 @@ func (r *LWKRpcWallet) SendToAddress(address string, amount Satoshi) (string, er
}

func (r *LWKRpcWallet) SendRawTx(txHex string) (string, error) {
ctx := context.Background()
ctx, cancel := context.WithTimeout(context.Background(), defaultContextTimeout)
defer cancel()
res, err := r.electrumClient.BroadcastTransaction(ctx, txHex)
if err != nil {
return "", err
Expand All @@ -225,7 +237,8 @@ func (r *LWKRpcWallet) getFeePerKb(ctx context.Context) SatPerKVByte {
}

func (r *LWKRpcWallet) GetFee(txSize int64) (Satoshi, error) {
ctx := context.Background()
ctx, cancel := context.WithTimeout(context.Background(), defaultContextTimeout)
defer cancel()
// assume largest witness
fee := r.getFeePerKb(ctx) * float64(txSize)
return Satoshi(fee), nil
Expand Down

0 comments on commit b72e410

Please sign in to comment.