Files
lspd/itest/cln_breez_client.go
2022-12-16 18:22:04 +01:00

156 lines
4.0 KiB
Go

package itest
import (
"bufio"
"fmt"
"os"
"path/filepath"
"sync"
"github.com/breez/lntest"
)
var pluginContent string = `#!/usr/bin/env python3
"""Use the openchannel hook to selectively opt-into zeroconf
"""
from pyln.client import Plugin
plugin = Plugin()
@plugin.hook('openchannel')
def on_openchannel(openchannel, plugin, **kwargs):
plugin.log(repr(openchannel))
mindepth = int(0)
plugin.log(f"This peer is in the zeroconf allowlist, setting mindepth={mindepth}")
return {'result': 'continue', 'mindepth': mindepth}
plugin.run()
`
var pluginStartupContent string = `python3 -m venv %s > /dev/null 2>&1
source %s > /dev/null 2>&1
pip install pyln-client > /dev/null 2>&1
python %s
`
type clnBreezClient struct {
name string
scriptDir string
pluginFilePath string
harness *lntest.TestHarness
isInitialized bool
node *lntest.ClnNode
mtx sync.Mutex
}
func newClnBreezClient(h *lntest.TestHarness, m *lntest.Miner, name string) BreezClient {
scriptDir := h.GetDirectory(name)
pluginFilePath := filepath.Join(scriptDir, "start_zero_conf_plugin.sh")
node := lntest.NewClnNode(
h,
m,
name,
fmt.Sprintf("--plugin=%s", pluginFilePath),
// NOTE: max-concurrent-htlcs is 30 on mainnet by default. In cln V22.11
// there is a check for 'all dust' commitment transactions. The max
// concurrent HTLCs of both sides of the channel * dust limit must be
// lower than the channel capacity in order to open a zero conf zero
// reserve channel. Relevant code:
// https://github.com/ElementsProject/lightning/blob/774d16a72e125e4ae4e312b9e3307261983bec0e/openingd/openingd.c#L481-L520
"--max-concurrent-htlcs=30",
)
return &clnBreezClient{
name: name,
harness: h,
node: node,
scriptDir: scriptDir,
pluginFilePath: pluginFilePath,
}
}
func (c *clnBreezClient) Name() string {
return c.name
}
func (c *clnBreezClient) Harness() *lntest.TestHarness {
return c.harness
}
func (c *clnBreezClient) Node() lntest.LightningNode {
return c.node
}
func (c *clnBreezClient) Start() {
c.mtx.Lock()
defer c.mtx.Unlock()
if !c.isInitialized {
c.initialize()
c.isInitialized = true
}
c.node.Start()
}
func (c *clnBreezClient) initialize() error {
var cleanups []*lntest.Cleanup
pythonFilePath := filepath.Join(c.scriptDir, "zero_conf_plugin.py")
pythonFile, err := os.OpenFile(pythonFilePath, os.O_CREATE|os.O_WRONLY, 0755)
if err != nil {
return fmt.Errorf("failed to create python file '%s': %v", pythonFilePath, err)
}
cleanups = append(cleanups, &lntest.Cleanup{
Name: fmt.Sprintf("%s: python file", c.name),
Fn: pythonFile.Close,
})
pythonWriter := bufio.NewWriter(pythonFile)
_, err = pythonWriter.WriteString(pluginContent)
if err != nil {
lntest.PerformCleanup(cleanups)
return fmt.Errorf("failed to write content to python file '%s': %v", pythonFilePath, err)
}
err = pythonWriter.Flush()
if err != nil {
lntest.PerformCleanup(cleanups)
return fmt.Errorf("failed to flush python file '%s': %v", pythonFilePath, err)
}
pluginFile, err := os.OpenFile(c.pluginFilePath, os.O_CREATE|os.O_WRONLY, 0755)
if err != nil {
lntest.PerformCleanup(cleanups)
return fmt.Errorf("failed to create plugin file '%s': %v", c.pluginFilePath, err)
}
cleanups = append(cleanups, &lntest.Cleanup{
Name: fmt.Sprintf("%s: python file", c.name),
Fn: pluginFile.Close,
})
pluginWriter := bufio.NewWriter(pluginFile)
venvDir := filepath.Join(c.scriptDir, "venv")
activatePath := filepath.Join(venvDir, "bin", "activate")
_, err = pluginWriter.WriteString(fmt.Sprintf(pluginStartupContent, venvDir, activatePath, pythonFilePath))
if err != nil {
lntest.PerformCleanup(cleanups)
return fmt.Errorf("failed to write content to plugin file '%s': %v", c.pluginFilePath, err)
}
err = pluginWriter.Flush()
if err != nil {
lntest.PerformCleanup(cleanups)
return fmt.Errorf("failed to flush plugin file '%s': %v", c.pluginFilePath, err)
}
lntest.PerformCleanup(cleanups)
return nil
}
func (c *clnBreezClient) Stop() error {
return c.node.Stop()
}