mirror of
https://github.com/aljazceru/lspd.git
synced 2025-12-19 06:44:23 +01:00
Spend unconfirmed utxos if minconfs=0
This commit is contained in:
@@ -76,7 +76,11 @@ func (c *ClnClient) IsConnected(destination []byte) (bool, error) {
|
||||
|
||||
func (c *ClnClient) OpenChannel(req *OpenChannelRequest) (*wire.OutPoint, error) {
|
||||
pubkey := hex.EncodeToString(req.Destination)
|
||||
minConfs := uint16(req.MinConfs)
|
||||
var minConfs *uint16
|
||||
if req.MinConfs != nil {
|
||||
m := uint16(*req.MinConfs)
|
||||
minConfs = &m
|
||||
}
|
||||
var minDepth *uint16
|
||||
if req.IsZeroConf {
|
||||
var d uint16 = 0
|
||||
@@ -110,7 +114,7 @@ func (c *ClnClient) OpenChannel(req *OpenChannelRequest) (*wire.OutPoint, error)
|
||||
glightning.NewSat(int(req.CapacitySat)),
|
||||
rate,
|
||||
!req.IsPrivate,
|
||||
&minConfs,
|
||||
minConfs,
|
||||
glightning.NewMsat(0),
|
||||
minDepth,
|
||||
glightning.NewSat(0),
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/breez/lspd/cln_plugin/proto"
|
||||
"github.com/breez/lspd/config"
|
||||
sphinx "github.com/lightningnetwork/lightning-onion"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/lightningnetwork/lnd/record"
|
||||
@@ -23,7 +24,7 @@ import (
|
||||
)
|
||||
|
||||
type ClnHtlcInterceptor struct {
|
||||
config *NodeConfig
|
||||
config *config.NodeConfig
|
||||
pluginAddress string
|
||||
client *ClnClient
|
||||
pluginClient proto.ClnPluginClient
|
||||
@@ -34,7 +35,7 @@ type ClnHtlcInterceptor struct {
|
||||
cancel context.CancelFunc
|
||||
}
|
||||
|
||||
func NewClnHtlcInterceptor(conf *NodeConfig) (*ClnHtlcInterceptor, error) {
|
||||
func NewClnHtlcInterceptor(conf *config.NodeConfig) (*ClnHtlcInterceptor, error) {
|
||||
if conf.Cln == nil {
|
||||
return nil, fmt.Errorf("missing cln config")
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package main
|
||||
package config
|
||||
|
||||
type NodeConfig struct {
|
||||
// Name of the LSP. If empty, the node's alias will be taken instead.
|
||||
@@ -35,7 +35,7 @@ type NodeConfig struct {
|
||||
|
||||
// Minimum number of confirmations inputs for zero conf channel opens should
|
||||
// have.
|
||||
MinConfs uint32 `json:"minConfs,string"`
|
||||
MinConfs *uint32 `json:"minConfs,string"`
|
||||
|
||||
// Smallest htlc amount routed over channels opened with the OpenChannel
|
||||
// rpc call.
|
||||
2
go.mod
2
go.mod
@@ -4,7 +4,7 @@ go 1.19
|
||||
|
||||
require (
|
||||
github.com/aws/aws-sdk-go v1.30.20
|
||||
github.com/breez/lntest v0.0.18
|
||||
github.com/breez/lntest v0.0.19
|
||||
github.com/btcsuite/btcd v0.23.3
|
||||
github.com/btcsuite/btcd/btcec/v2 v2.2.1
|
||||
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/breez/lspd/chain"
|
||||
"github.com/breez/lspd/config"
|
||||
"github.com/btcsuite/btcd/btcec/v2"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
sphinx "github.com/lightningnetwork/lightning-onion"
|
||||
@@ -49,7 +50,7 @@ type interceptResult struct {
|
||||
onionBlob []byte
|
||||
}
|
||||
|
||||
func intercept(client LightningClient, config *NodeConfig, nextHop string, reqPaymentHash []byte, reqOutgoingAmountMsat uint64, reqOutgoingExpiry uint32, reqIncomingExpiry uint32) interceptResult {
|
||||
func intercept(client LightningClient, config *config.NodeConfig, nextHop string, reqPaymentHash []byte, reqOutgoingAmountMsat uint64, reqOutgoingExpiry uint32, reqIncomingExpiry uint32) interceptResult {
|
||||
reqPaymentHashStr := hex.EncodeToString(reqPaymentHash)
|
||||
resp, _, _ := payHashGroup.Do(reqPaymentHashStr, func() (interface{}, error) {
|
||||
paymentHash, paymentSecret, destination, incomingAmountMsat, outgoingAmountMsat, channelPoint, err := paymentInfo(reqPaymentHash)
|
||||
@@ -224,7 +225,7 @@ func intercept(client LightningClient, config *NodeConfig, nextHop string, reqPa
|
||||
return resp.(interceptResult)
|
||||
}
|
||||
|
||||
func checkPayment(config *NodeConfig, incomingAmountMsat, outgoingAmountMsat int64) error {
|
||||
func checkPayment(config *config.NodeConfig, incomingAmountMsat, outgoingAmountMsat int64) error {
|
||||
fees := incomingAmountMsat * config.ChannelFeePermyriad / 10_000 / 1_000 * 1_000
|
||||
if fees < config.ChannelMinimumFeeMsat {
|
||||
fees = config.ChannelMinimumFeeMsat
|
||||
@@ -235,7 +236,7 @@ func checkPayment(config *NodeConfig, incomingAmountMsat, outgoingAmountMsat int
|
||||
return nil
|
||||
}
|
||||
|
||||
func openChannel(client LightningClient, config *NodeConfig, paymentHash, destination []byte, incomingAmountMsat int64) (*wire.OutPoint, error) {
|
||||
func openChannel(client LightningClient, config *config.NodeConfig, paymentHash, destination []byte, incomingAmountMsat int64) (*wire.OutPoint, error) {
|
||||
capacity := incomingAmountMsat/1000 + config.AdditionalChannelCapacity
|
||||
if capacity == config.PublicChannelAmount {
|
||||
capacity++
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"syscall"
|
||||
|
||||
"github.com/breez/lntest"
|
||||
"github.com/breez/lspd/config"
|
||||
lspd "github.com/breez/lspd/rpc"
|
||||
"github.com/btcsuite/btcd/btcec/v2"
|
||||
ecies "github.com/ecies/go/v2"
|
||||
@@ -41,7 +42,7 @@ type clnLspNodeRuntime struct {
|
||||
cleanups []*lntest.Cleanup
|
||||
}
|
||||
|
||||
func NewClnLspdNode(h *lntest.TestHarness, m *lntest.Miner, name string) LspNode {
|
||||
func NewClnLspdNode(h *lntest.TestHarness, m *lntest.Miner, name string, nodeConfig *config.NodeConfig) LspNode {
|
||||
scriptDir := h.GetDirectory("lspd")
|
||||
pluginBinary := *clnPluginExec
|
||||
pluginPort, err := lntest.GetPort()
|
||||
@@ -60,12 +61,11 @@ func NewClnLspdNode(h *lntest.TestHarness, m *lntest.Miner, name string) LspNode
|
||||
"--dev-allowdustreserve=true",
|
||||
}
|
||||
lightningNode := lntest.NewClnNode(h, m, name, args...)
|
||||
cln := fmt.Sprintf(
|
||||
`{ "pluginAddress": "%s", "socketPath": "%s" }`,
|
||||
pluginAddress,
|
||||
filepath.Join(lightningNode.SocketDir(), lightningNode.SocketFile()),
|
||||
)
|
||||
lspbase, err := newLspd(h, name, nil, &cln)
|
||||
cln := &config.ClnConfig{
|
||||
PluginAddress: pluginAddress,
|
||||
SocketPath: filepath.Join(lightningNode.SocketDir(), lightningNode.SocketFile()),
|
||||
}
|
||||
lspbase, err := newLspd(h, name, nodeConfig, nil, cln)
|
||||
if err != nil {
|
||||
h.T.Fatalf("failed to initialize lspd")
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ func TestConfigParameters(t *testing.T) {
|
||||
m := lntest.NewMiner(h)
|
||||
m.Start()
|
||||
|
||||
lsp := NewClnLspdNode(h, m, "lsp")
|
||||
lsp := NewClnLspdNode(h, m, "lsp", nil)
|
||||
lsp.Start()
|
||||
|
||||
log.Printf("Waiting %v to allow lsp server to activate.", htlcInterceptorDelay)
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"syscall"
|
||||
|
||||
"github.com/breez/lntest"
|
||||
"github.com/breez/lspd/config"
|
||||
lspd "github.com/breez/lspd/rpc"
|
||||
"github.com/btcsuite/btcd/btcec/v2"
|
||||
ecies "github.com/ecies/go/v2"
|
||||
@@ -37,7 +38,7 @@ type lndLspNodeRuntime struct {
|
||||
cleanups []*lntest.Cleanup
|
||||
}
|
||||
|
||||
func NewLndLspdNode(h *lntest.TestHarness, m *lntest.Miner, name string) LspNode {
|
||||
func NewLndLspdNode(h *lntest.TestHarness, m *lntest.Miner, name string, nodeConfig *config.NodeConfig) LspNode {
|
||||
args := []string{
|
||||
"--protocol.zero-conf",
|
||||
"--protocol.option-scid-alias",
|
||||
@@ -50,12 +51,12 @@ func NewLndLspdNode(h *lntest.TestHarness, m *lntest.Miner, name string) LspNode
|
||||
}
|
||||
|
||||
lightningNode := lntest.NewLndNode(h, m, name, args...)
|
||||
j, _ := json.Marshal(map[string]string{
|
||||
"address": lightningNode.GrpcHost(),
|
||||
"cert": string(lightningNode.TlsCert()),
|
||||
"macaroon": hex.EncodeToString(lightningNode.Macaroon())})
|
||||
lnd := string(j)
|
||||
lspBase, err := newLspd(h, name, &lnd, nil)
|
||||
lnd := &config.LndConfig{
|
||||
Address: lightningNode.GrpcHost(),
|
||||
Cert: string(lightningNode.TlsCert()),
|
||||
Macaroon: hex.EncodeToString(lightningNode.Macaroon()),
|
||||
}
|
||||
lspBase, err := newLspd(h, name, nodeConfig, lnd, nil)
|
||||
if err != nil {
|
||||
h.T.Fatalf("failed to initialize lspd")
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ package itest
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
@@ -11,6 +13,7 @@ import (
|
||||
"path/filepath"
|
||||
|
||||
"github.com/breez/lntest"
|
||||
"github.com/breez/lspd/config"
|
||||
lspd "github.com/breez/lspd/rpc"
|
||||
"github.com/btcsuite/btcd/btcec/v2"
|
||||
"github.com/decred/dcrd/dcrec/secp256k1/v4"
|
||||
@@ -58,7 +61,7 @@ type lspBase struct {
|
||||
postgresBackend *PostgresContainer
|
||||
}
|
||||
|
||||
func newLspd(h *lntest.TestHarness, name string, lnd *string, cln *string, envExt ...string) (*lspBase, error) {
|
||||
func newLspd(h *lntest.TestHarness, name string, nodeConfig *config.NodeConfig, lnd *config.LndConfig, cln *config.ClnConfig, envExt ...string) (*lspBase, error) {
|
||||
scriptDir := h.GetDirectory(fmt.Sprintf("lspd-%s", name))
|
||||
log.Printf("%s: Creating LSPD in dir %s", name, scriptDir)
|
||||
|
||||
@@ -88,32 +91,45 @@ func newLspd(h *lntest.TestHarness, name string, lnd *string, cln *string, envEx
|
||||
eciesPubl := ecies.NewPrivateKeyFromBytes(lspdPrivateKeyBytes).PublicKey
|
||||
host := "localhost"
|
||||
grpcAddress := fmt.Sprintf("%s:%d", host, lspdPort)
|
||||
var ext string
|
||||
if lnd != nil {
|
||||
ext = fmt.Sprintf(`"lnd": %s`, *lnd)
|
||||
} else if cln != nil {
|
||||
ext = fmt.Sprintf(`"cln": %s`, *cln)
|
||||
} else {
|
||||
h.T.Fatalf("%s: need either lnd or cln config", name)
|
||||
minConfs := uint32(1)
|
||||
conf := &config.NodeConfig{
|
||||
Name: name,
|
||||
LspdPrivateKey: hex.EncodeToString(lspdPrivateKeyBytes),
|
||||
Token: "hello",
|
||||
Host: "host:port",
|
||||
PublicChannelAmount: 1000183,
|
||||
ChannelAmount: 100000,
|
||||
ChannelPrivate: false,
|
||||
TargetConf: 6,
|
||||
MinConfs: &minConfs,
|
||||
MinHtlcMsat: 600,
|
||||
BaseFeeMsat: 1000,
|
||||
FeeRate: 0.000001,
|
||||
TimeLockDelta: 144,
|
||||
ChannelFeePermyriad: 40,
|
||||
ChannelMinimumFeeMsat: 2000000,
|
||||
AdditionalChannelCapacity: 100000,
|
||||
MaxInactiveDuration: 3888000,
|
||||
Lnd: lnd,
|
||||
Cln: cln,
|
||||
}
|
||||
|
||||
nodes := fmt.Sprintf(
|
||||
`NODES='[ { "name": "%s", "lspdPrivateKey": "%x", "token": "hello", "host": "host:port",`+
|
||||
` "publicChannelAmount": "1000183", "channelAmount": "100000", "channelPrivate": false,`+
|
||||
` "targetConf": "6", "minConfs": "1", "minHtlcMsat": "600", "baseFeeMsat": "1000", "feeRate": "0.000001",`+
|
||||
` "timeLockDelta": "144", "channelFeePermyriad": "40", "channelMinimumFeeMsat": "2000000",`+
|
||||
` "additionalChannelCapacity": "100000", "maxInactiveDuration": "3888000", %s}]'`,
|
||||
name,
|
||||
lspdPrivateKeyBytes,
|
||||
ext,
|
||||
)
|
||||
if nodeConfig != nil {
|
||||
if nodeConfig.MinConfs != nil {
|
||||
conf.MinConfs = nodeConfig.MinConfs
|
||||
}
|
||||
}
|
||||
|
||||
log.Printf("%+v", conf)
|
||||
confJson, _ := json.Marshal(conf)
|
||||
nodes := fmt.Sprintf(`NODES='[%s]'`, string(confJson))
|
||||
env := []string{
|
||||
nodes,
|
||||
fmt.Sprintf("DATABASE_URL=%s", postgresBackend.ConnectionString()),
|
||||
fmt.Sprintf("LISTEN_ADDRESS=%s", grpcAddress),
|
||||
fmt.Sprintf("USE_MEMPOOL_FEE_ESTIMATION=true"),
|
||||
fmt.Sprintf("MEMPOOL_API_BASE_URL=https://mempool.space/api/v1/"),
|
||||
fmt.Sprintf("MEMPOOL_PRIORITY=economy"),
|
||||
"USE_MEMPOOL_FEE_ESTIMATION=true",
|
||||
"MEMPOOL_API_BASE_URL=https://mempool.space/api/v1/",
|
||||
"MEMPOOL_PRIORITY=economy",
|
||||
}
|
||||
|
||||
env = append(env, envExt...)
|
||||
|
||||
@@ -7,31 +7,55 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/breez/lntest"
|
||||
"github.com/breez/lspd/config"
|
||||
)
|
||||
|
||||
var defaultTimeout time.Duration = time.Second * 120
|
||||
|
||||
func TestLspd(t *testing.T) {
|
||||
testCases := allTestCases
|
||||
runTests(t, testCases, "LND-lspd", func(h *lntest.TestHarness, m *lntest.Miner) (LspNode, BreezClient) {
|
||||
return NewLndLspdNode(h, m, "lsp"), newLndBreezClient(h, m, "breez-client")
|
||||
})
|
||||
|
||||
runTests(t, testCases, "CLN-lspd", func(h *lntest.TestHarness, m *lntest.Miner) (LspNode, BreezClient) {
|
||||
return NewClnLspdNode(h, m, "lsp"), newClnBreezClient(h, m, "breez-client")
|
||||
})
|
||||
runTests(t, testCases, "LND-lspd", lndLspFunc, lndClientFunc)
|
||||
runTests(t, testCases, "CLN-lspd", clnLspFunc, clnClientFunc)
|
||||
}
|
||||
|
||||
func runTests(t *testing.T, testCases []*testCase, prefix string, nodesFunc func(h *lntest.TestHarness, m *lntest.Miner) (LspNode, BreezClient)) {
|
||||
func lndLspFunc(h *lntest.TestHarness, m *lntest.Miner, c *config.NodeConfig) LspNode {
|
||||
return NewLndLspdNode(h, m, "lsp", c)
|
||||
}
|
||||
|
||||
func clnLspFunc(h *lntest.TestHarness, m *lntest.Miner, c *config.NodeConfig) LspNode {
|
||||
return NewClnLspdNode(h, m, "lsp", c)
|
||||
}
|
||||
|
||||
func lndClientFunc(h *lntest.TestHarness, m *lntest.Miner) BreezClient {
|
||||
return newLndBreezClient(h, m, "breez-client")
|
||||
}
|
||||
|
||||
func clnClientFunc(h *lntest.TestHarness, m *lntest.Miner) BreezClient {
|
||||
return newClnBreezClient(h, m, "breez-client")
|
||||
}
|
||||
|
||||
func runTests(
|
||||
t *testing.T,
|
||||
testCases []*testCase,
|
||||
prefix string,
|
||||
lspFunc LspFunc,
|
||||
clientFunc ClientFunc,
|
||||
) {
|
||||
for _, testCase := range testCases {
|
||||
testCase := testCase
|
||||
t.Run(fmt.Sprintf("%s: %s", prefix, testCase.name), func(t *testing.T) {
|
||||
runTest(t, testCase, prefix, nodesFunc)
|
||||
runTest(t, testCase, prefix, lspFunc, clientFunc)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func runTest(t *testing.T, testCase *testCase, prefix string, nodesFunc func(h *lntest.TestHarness, m *lntest.Miner) (LspNode, BreezClient)) {
|
||||
func runTest(
|
||||
t *testing.T,
|
||||
testCase *testCase,
|
||||
prefix string,
|
||||
lspFunc LspFunc,
|
||||
clientFunc ClientFunc,
|
||||
) {
|
||||
log.Printf("%s: Running test case '%s'", prefix, testCase.name)
|
||||
var dd time.Duration
|
||||
to := testCase.timeout
|
||||
@@ -49,23 +73,30 @@ func runTest(t *testing.T, testCase *testCase, prefix string, nodesFunc func(h *
|
||||
miner := lntest.NewMiner(h)
|
||||
miner.Start()
|
||||
log.Printf("Creating lsp")
|
||||
lsp, c := nodesFunc(h, miner)
|
||||
lsp.Start()
|
||||
var lsp LspNode
|
||||
if !testCase.skipCreateLsp {
|
||||
lsp = lspFunc(h, miner, nil)
|
||||
lsp.Start()
|
||||
}
|
||||
c := clientFunc(h, miner)
|
||||
c.Start()
|
||||
log.Printf("Run testcase")
|
||||
testCase.test(&testParams{
|
||||
t: t,
|
||||
h: h,
|
||||
m: miner,
|
||||
c: c,
|
||||
lsp: lsp,
|
||||
t: t,
|
||||
h: h,
|
||||
m: miner,
|
||||
c: c,
|
||||
lsp: lsp,
|
||||
lspFunc: lspFunc,
|
||||
clientFunc: clientFunc,
|
||||
})
|
||||
}
|
||||
|
||||
type testCase struct {
|
||||
name string
|
||||
test func(t *testParams)
|
||||
timeout time.Duration
|
||||
name string
|
||||
test func(t *testParams)
|
||||
skipCreateLsp bool
|
||||
timeout time.Duration
|
||||
}
|
||||
|
||||
var allTestCases = []*testCase{
|
||||
@@ -105,4 +136,9 @@ var allTestCases = []*testCase{
|
||||
name: "registerPaymentWithTag",
|
||||
test: registerPaymentWithTag,
|
||||
},
|
||||
{
|
||||
name: "testOpenZeroConfUtxo",
|
||||
test: testOpenZeroConfUtxo,
|
||||
skipCreateLsp: true,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -4,14 +4,20 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/breez/lntest"
|
||||
"github.com/breez/lspd/config"
|
||||
)
|
||||
|
||||
type LspFunc func(h *lntest.TestHarness, m *lntest.Miner, c *config.NodeConfig) LspNode
|
||||
type ClientFunc func(h *lntest.TestHarness, m *lntest.Miner) BreezClient
|
||||
|
||||
type testParams struct {
|
||||
t *testing.T
|
||||
h *lntest.TestHarness
|
||||
m *lntest.Miner
|
||||
c BreezClient
|
||||
lsp LspNode
|
||||
t *testing.T
|
||||
h *lntest.TestHarness
|
||||
m *lntest.Miner
|
||||
c BreezClient
|
||||
lsp LspNode
|
||||
lspFunc LspFunc
|
||||
clientFunc ClientFunc
|
||||
}
|
||||
|
||||
func (h *testParams) T() *testing.T {
|
||||
|
||||
72
itest/zero_conf_utxo_test.go
Normal file
72
itest/zero_conf_utxo_test.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package itest
|
||||
|
||||
import (
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/breez/lntest"
|
||||
"github.com/breez/lspd/config"
|
||||
lspd "github.com/breez/lspd/rpc"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func testOpenZeroConfUtxo(p *testParams) {
|
||||
alice := lntest.NewClnNode(p.h, p.m, "Alice")
|
||||
alice.Start()
|
||||
alice.Fund(10000000)
|
||||
|
||||
minConfs := uint32(0)
|
||||
lsp := p.lspFunc(p.h, p.m, &config.NodeConfig{MinConfs: &minConfs})
|
||||
lsp.Start()
|
||||
|
||||
log.Print("Opening channel between Alice and the lsp")
|
||||
channel := alice.OpenChannel(lsp.LightningNode(), &lntest.OpenChannelOptions{
|
||||
AmountSat: publicChanAmount,
|
||||
})
|
||||
channelId := alice.WaitForChannelReady(channel)
|
||||
|
||||
// Send an unconfirmed utxo to the lsp
|
||||
initialHeight := p.m.GetBlockHeight()
|
||||
addr := lsp.LightningNode().GetNewAddress()
|
||||
p.m.SendToAddress(addr, 200000)
|
||||
|
||||
log.Printf("Adding bob's invoices")
|
||||
outerAmountMsat := uint64(2100000)
|
||||
innerAmountMsat, lspAmountMsat := calculateInnerAmountMsat(lsp, outerAmountMsat)
|
||||
description := "Please pay me"
|
||||
innerInvoice, outerInvoice := GenerateInvoices(p.BreezClient(),
|
||||
generateInvoicesRequest{
|
||||
innerAmountMsat: innerAmountMsat,
|
||||
outerAmountMsat: outerAmountMsat,
|
||||
description: description,
|
||||
lsp: lsp,
|
||||
})
|
||||
|
||||
log.Print("Connecting bob to lspd")
|
||||
p.BreezClient().Node().ConnectPeer(lsp.LightningNode())
|
||||
|
||||
log.Printf("Registering payment with lsp")
|
||||
RegisterPayment(lsp, &lspd.PaymentInformation{
|
||||
PaymentHash: innerInvoice.paymentHash,
|
||||
PaymentSecret: innerInvoice.paymentSecret,
|
||||
Destination: p.BreezClient().Node().NodeId(),
|
||||
IncomingAmountMsat: int64(outerAmountMsat),
|
||||
OutgoingAmountMsat: int64(lspAmountMsat),
|
||||
})
|
||||
|
||||
// TODO: Fix race waiting for htlc interceptor.
|
||||
log.Printf("Waiting %v to allow htlc interceptor to activate.", htlcInterceptorDelay)
|
||||
<-time.After(htlcInterceptorDelay)
|
||||
log.Printf("Alice paying")
|
||||
route := constructRoute(lsp.LightningNode(), p.BreezClient().Node(), channelId, lntest.NewShortChanIDFromString("1x0x0"), outerAmountMsat)
|
||||
payResp, err := alice.PayViaRoute(outerAmountMsat, outerInvoice.paymentHash, outerInvoice.paymentSecret, route)
|
||||
lntest.CheckError(p.t, err)
|
||||
bobInvoice := p.BreezClient().Node().GetInvoice(payResp.PaymentHash)
|
||||
|
||||
assert.Equal(p.t, payResp.PaymentPreimage, bobInvoice.PaymentPreimage)
|
||||
assert.Equal(p.t, innerAmountMsat, bobInvoice.AmountReceivedMsat)
|
||||
|
||||
// Make sure there's not accidently a block mined in between
|
||||
finalHeight := p.m.GetBlockHeight()
|
||||
assert.Equal(p.t, initialHeight, finalHeight)
|
||||
}
|
||||
@@ -21,7 +21,7 @@ type OpenChannelRequest struct {
|
||||
MinHtlcMsat uint64
|
||||
IsPrivate bool
|
||||
IsZeroConf bool
|
||||
MinConfs uint32
|
||||
MinConfs *uint32
|
||||
FeeSatPerVByte *float64
|
||||
TargetConf *uint32
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"log"
|
||||
|
||||
"github.com/breez/lspd/basetypes"
|
||||
"github.com/breez/lspd/config"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/lightningnetwork/lnd/htlcswitch/hop"
|
||||
"github.com/lightningnetwork/lnd/lnrpc"
|
||||
@@ -24,7 +25,7 @@ type LndClient struct {
|
||||
conn *grpc.ClientConn
|
||||
}
|
||||
|
||||
func NewLndClient(conf *LndConfig) (*LndClient, error) {
|
||||
func NewLndClient(conf *config.LndConfig) (*LndClient, error) {
|
||||
_, err := hex.DecodeString(conf.Macaroon)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to decode macaroon: %w", err)
|
||||
@@ -103,7 +104,14 @@ func (c *LndClient) OpenChannel(req *OpenChannelRequest) (*wire.OutPoint, error)
|
||||
Private: req.IsPrivate,
|
||||
CommitmentType: lnrpc.CommitmentType_ANCHORS,
|
||||
ZeroConf: req.IsZeroConf,
|
||||
MinConfs: int32(req.MinConfs),
|
||||
}
|
||||
|
||||
if req.MinConfs != nil {
|
||||
minConfs := *req.MinConfs
|
||||
lnReq.MinConfs = int32(minConfs)
|
||||
if minConfs == 0 {
|
||||
lnReq.SpendUnconfirmed = true
|
||||
}
|
||||
}
|
||||
|
||||
if req.FeeSatPerVByte != nil {
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/breez/lspd/config"
|
||||
"github.com/lightningnetwork/lnd/lnrpc"
|
||||
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
@@ -14,7 +15,7 @@ import (
|
||||
)
|
||||
|
||||
type LndHtlcInterceptor struct {
|
||||
config *NodeConfig
|
||||
config *config.NodeConfig
|
||||
client *LndClient
|
||||
stopRequested bool
|
||||
initWg sync.WaitGroup
|
||||
@@ -23,7 +24,7 @@ type LndHtlcInterceptor struct {
|
||||
cancel context.CancelFunc
|
||||
}
|
||||
|
||||
func NewLndHtlcInterceptor(conf *NodeConfig) (*LndHtlcInterceptor, error) {
|
||||
func NewLndHtlcInterceptor(conf *config.NodeConfig) (*LndHtlcInterceptor, error) {
|
||||
if conf.Lnd == nil {
|
||||
return nil, fmt.Errorf("missing lnd configuration")
|
||||
}
|
||||
|
||||
3
main.go
3
main.go
@@ -11,6 +11,7 @@ import (
|
||||
"syscall"
|
||||
|
||||
"github.com/breez/lspd/chain"
|
||||
"github.com/breez/lspd/config"
|
||||
"github.com/breez/lspd/mempool"
|
||||
"github.com/btcsuite/btcd/btcec/v2"
|
||||
)
|
||||
@@ -26,7 +27,7 @@ func main() {
|
||||
}
|
||||
|
||||
n := os.Getenv("NODES")
|
||||
var nodes []*NodeConfig
|
||||
var nodes []*config.NodeConfig
|
||||
err := json.Unmarshal([]byte(n), &nodes)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to unmarshal NODES env: %v", err)
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/breez/lspd/btceclegacy"
|
||||
"github.com/breez/lspd/config"
|
||||
lspdrpc "github.com/breez/lspd/rpc"
|
||||
ecies "github.com/ecies/go/v2"
|
||||
"github.com/golang/protobuf/proto"
|
||||
@@ -39,7 +40,7 @@ type server struct {
|
||||
|
||||
type node struct {
|
||||
client LightningClient
|
||||
nodeConfig *NodeConfig
|
||||
nodeConfig *config.NodeConfig
|
||||
privateKey *btcec.PrivateKey
|
||||
publicKey *btcec.PublicKey
|
||||
eciesPrivateKey *ecies.PrivateKey
|
||||
@@ -259,7 +260,7 @@ func (s *server) CheckChannels(ctx context.Context, in *lspdrpc.Encrypted) (*lsp
|
||||
return &lspdrpc.Encrypted{Data: encrypted}, nil
|
||||
}
|
||||
|
||||
func NewGrpcServer(configs []*NodeConfig, address string, certmagicDomain string) (*server, error) {
|
||||
func NewGrpcServer(configs []*config.NodeConfig, address string, certmagicDomain string) (*server, error) {
|
||||
if len(configs) == 0 {
|
||||
return nil, fmt.Errorf("no nodes supplied")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user