Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

probe payment as sanity check #260

Merged
merged 7 commits into from
Dec 19, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ test-bitcoin-cln: test-bins
'Test_ClnCln_Bitcoin_SwapIn|'\
'Test_ClnLnd_Bitcoin_SwapOut|'\
'Test_ClnLnd_Bitcoin_SwapIn|'\
'Test_ClnCln_ExcessiveAmount)'\
'Test_ClnCln_ExcessiveAmount|'\
'Test_ClnCln_StuckChannels)'\
./test
.PHONY: test-bitoin-cln

Expand Down
5 changes: 1 addition & 4 deletions policy/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,7 @@ type Policy struct {
// MinSwapAmountMsat is the minimum swap amount in msat that is needed to
// perform a swap. Below this amount it might be uneconomical to do a swap
// due to the on-chain costs.
// TODO: This can not be set in the policy by now but this is the place
// where this value belongs. Eventually we might want to make this value
// editable as a policy setting.
MinSwapAmountMsat uint64 `json:"min_swap_amount_msat"`
MinSwapAmountMsat uint64 `json:"min_swap_amount_msat" long:"min_swap_amount_msat" description:"The minimum amount in msat that is needed to perform a swap."`

// AllowNewSwaps can be used to disallow any new swaps. This can be useful
// when we want to upgrade the node and do not want to allow for any new
Expand Down
74 changes: 74 additions & 0 deletions test/bitcoin_cln_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1141,3 +1141,77 @@ func Test_ClnCln_ExcessiveAmount(t *testing.T) {
})

}

// Test_ClnCln_StuckChannels tests that the swap fails if the channel is stuck.
// For more information about stuck channel, please check the link.
// https://github.com/lightning/bolts/issues/728
func Test_ClnCln_StuckChannels(t *testing.T) {
IsIntegrationTest(t)
t.Parallel()

require := require.New(t)
// repro by using the push_msat in the open_channel.
// Assumption that feperkw is 253perkw in reg test.
bitcoind, lightningds, scid := clnclnSetupWithConfig(t, 3794, 3573, []string{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Numbers checked. They match 1% reserve 37940 msat and a CommitTx fee of 183172 msat.
This gives the funder 221112 msat for a stuck channel. The configuration leaves 221 sat on the funders side which results in a stuck channel.

"--dev-bitcoind-poll=1",
"--dev-fast-gossip",
"--large-channels",
"--min-capacity-sat=1000",
})

defer func() {
if t.Failed() {
filter := os.Getenv("PEERSWAP_TEST_FILTER")
pprintFail(
tailableProcess{
p: bitcoind.DaemonProcess,
lines: defaultLines,
},
tailableProcess{
p: lightningds[0].DaemonProcess,
filter: filter,
lines: defaultLines,
},
tailableProcess{
p: lightningds[1].DaemonProcess,
lines: defaultLines,
},
)
}
}()

var channelBalances []uint64
var walletBalances []uint64
for _, lightningd := range lightningds {
b, err := lightningd.GetBtcBalanceSat()
require.NoError(err)
walletBalances = append(walletBalances, b)

b, err = lightningd.GetChannelBalanceSat(scid)
require.NoError(err)
channelBalances = append(channelBalances, b)
}

params := &testParams{
swapAmt: channelBalances[0],
scid: scid,
origTakerWallet: walletBalances[0],
origMakerWallet: walletBalances[1],
origTakerBalance: channelBalances[0],
origMakerBalance: channelBalances[1],
takerNode: lightningds[0],
makerNode: lightningds[1],
takerPeerswap: lightningds[0].DaemonProcess,
makerPeerswap: lightningds[1].DaemonProcess,
chainRpc: bitcoind.RpcProxy,
chaind: bitcoind,
confirms: BitcoinConfirms,
csv: BitcoinCsv,
swapType: swap.SWAPTYPE_IN,
}

// Swap in should fail by probing payment as the channel is stuck.
var response map[string]interface{}
err := lightningds[1].Rpc.Request(&clightning.SwapIn{SatAmt: 100, ShortChannelId: params.scid, Asset: "btc"}, &response)
assert.Error(t, err)
}
19 changes: 10 additions & 9 deletions test/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ const (
)

func clnclnSetup(t *testing.T, fundAmt uint64) (*testframework.BitcoinNode, []*testframework.CLightningNode, string) {
return clnclnSetupWithConfig(t, fundAmt, []string{
return clnclnSetupWithConfig(t, fundAmt, 0, []string{
"--dev-bitcoind-poll=1",
"--dev-fast-gossip",
"--large-channels",
})
}

func clnclnSetupWithConfig(t *testing.T, fundAmt uint64, clnConf []string) (*testframework.BitcoinNode, []*testframework.CLightningNode, string) {
func clnclnSetupWithConfig(t *testing.T, fundAmt, pushAmt uint64, clnConf []string) (*testframework.BitcoinNode, []*testframework.CLightningNode, string) {
// Get PeerSwap plugin path and test dir
_, filename, _, _ := runtime.Caller(0)
pathToPlugin := filepath.Join(filename, "..", "..", "out", "test-builds", "peerswap")
Expand All @@ -65,7 +65,8 @@ func clnclnSetupWithConfig(t *testing.T, fundAmt uint64, clnConf []string) (*tes
if err != nil {
t.Fatal("could not create dir", err)
}
err = os.WriteFile(filepath.Join(lightningd.GetDataDir(), "peerswap", "policy.conf"), []byte("accept_all_peers=1\n"), os.ModePerm)
err = os.WriteFile(filepath.Join(lightningd.GetDataDir(), "peerswap", "policy.conf"),
[]byte("accept_all_peers=1\nmin_swap_amount_msat=1\n"), os.ModePerm)
if err != nil {
t.Fatal("could not create policy file", err)
}
Expand Down Expand Up @@ -107,7 +108,7 @@ func clnclnSetupWithConfig(t *testing.T, fundAmt uint64, clnConf []string) (*tes
}

// Setup channel ([0] fundAmt(10^7) ---- 0 [1])
scid, err := lightningds[0].OpenChannel(lightningds[1], fundAmt, true, true, true)
scid, err := lightningds[0].OpenChannel(lightningds[1], fundAmt, pushAmt, true, true, true)
if err != nil {
t.Fatalf("lightingds[0].OpenChannel() %v", err)
}
Expand Down Expand Up @@ -185,7 +186,7 @@ func lndlndSetup(t *testing.T, fundAmt uint64) (*testframework.BitcoinNode, []*t
}

// Setup channel ([0] fundAmt(10^7) ---- 0 [1])
scid, err := lightningds[0].OpenChannel(lightningds[1], fundAmt, true, true, true)
scid, err := lightningds[0].OpenChannel(lightningds[1], fundAmt, 0, true, true, true)
if err != nil {
t.Fatalf("lightingds[0].OpenChannel() %v", err)
}
Expand Down Expand Up @@ -312,7 +313,7 @@ func mixedSetup(t *testing.T, fundAmt uint64, funder fundingNode) (*testframewor
}

// Setup channel ([0] fundAmt(10^7) ---- 0 [1])
scid, err := lightningds[0].OpenChannel(lightningds[1], fundAmt, true, true, true)
scid, err := lightningds[0].OpenChannel(lightningds[1], fundAmt, 0, true, true, true)
if err != nil {
t.Fatalf("lightningds[0].OpenChannel() %v", err)
}
Expand Down Expand Up @@ -454,7 +455,7 @@ func clnclnElementsSetup(t *testing.T, fundAmt uint64) (*testframework.BitcoinNo
require.NoError(t, err)

// Setup channel ([0] fundAmt(10^7) ---- 0 [1]).
scid, err := lightningds[0].OpenChannel(lightningds[1], fundAmt, true, true, true)
scid, err := lightningds[0].OpenChannel(lightningds[1], fundAmt, 0, true, true, true)
if err != nil {
t.Fatalf("lightingds[0].OpenChannel() %v", err)
}
Expand Down Expand Up @@ -575,7 +576,7 @@ func lndlndElementsSetup(t *testing.T, fundAmt uint64) (*testframework.BitcoinNo
require.NoError(t, err)

// Setup channel ([0] fundAmt(10^7) ---- 0 [1])
scid, err := lightningds[0].OpenChannel(lightningds[1], fundAmt, true, true, true)
scid, err := lightningds[0].OpenChannel(lightningds[1], fundAmt, 0, true, true, true)
if err != nil {
t.Fatalf("lightingds[0].OpenChannel() %v", err)
}
Expand Down Expand Up @@ -764,7 +765,7 @@ func mixedElementsSetup(t *testing.T, fundAmt uint64, funder fundingNode) (*test
}

// Setup channel ([0] fundAmt(10^7) ---- 0 [1])
scid, err := lightningds[0].OpenChannel(lightningds[1], fundAmt, true, true, true)
scid, err := lightningds[0].OpenChannel(lightningds[1], fundAmt, 0, true, true, true)
if err != nil {
t.Fatalf("cln.OpenChannel() %v", err)
}
Expand Down
2 changes: 1 addition & 1 deletion test/wumbo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func Test_Wumbo(t *testing.T) {
}

// Test Swap-out
bitcoind, lightningds, scid := clnclnSetupWithConfig(t, maxChanSize, options)
bitcoind, lightningds, scid := clnclnSetupWithConfig(t, maxChanSize, 0, options)
defer func() {
if t.Failed() {
filter := os.Getenv("PEERSWAP_TEST_FILTER")
Expand Down
5 changes: 3 additions & 2 deletions testframework/clightning.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ func (n *CLightningNode) FundWallet(sats uint64, mineBlock bool) (string, error)
return addr, nil
}

func (n *CLightningNode) OpenChannel(remote LightningNode, capacity uint64, connect, confirm, waitForActiveChannel bool) (string, error) {
func (n *CLightningNode) OpenChannel(remote LightningNode, capacity, pushAmt uint64, connect, confirm, waitForActiveChannel bool) (string, error) {
_, err := n.FundWallet(uint64(1.5*float64(capacity)), true)
if err != nil {
return "", fmt.Errorf("FundWallet() %w", err)
Expand All @@ -317,7 +317,8 @@ func (n *CLightningNode) OpenChannel(remote LightningNode, capacity uint64, conn
}
}

fr, err := n.Rpc.FundChannel(remote.Id(), &glightning.Sat{Value: capacity})
pushAmtSat := &glightning.Sat{Value: pushAmt}
fr, err := n.Rpc.FundChannelExt(remote.Id(), &glightning.Sat{Value: capacity}, nil, true, nil, pushAmtSat.ConvertMsat())
if err != nil {
return "", fmt.Errorf("FundChannel() %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion testframework/lightning.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ type LightningNode interface {

Connect(peer LightningNode, waitForConnection bool) error
FundWallet(sats uint64, mineBlock bool) (addr string, err error)
OpenChannel(peer LightningNode, capacity uint64, connect, confirm, waitForChannelActive bool) (scid string, err error)
OpenChannel(peer LightningNode, capacity, pushAmt uint64, connect, confirm, waitForChannelActive bool) (scid string, err error)

IsBlockHeightSynced() (bool, error)
IsChannelActive(scid string) (bool, error)
Expand Down
3 changes: 2 additions & 1 deletion testframework/lnd.go
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ func (n *LndNode) FundWallet(sats uint64, mineBlock bool) (string, error) {
return addr.Address, nil
}

func (n *LndNode) OpenChannel(peer LightningNode, capacity uint64, connect, confirm, waitForChannelActive bool) (string, error) {
func (n *LndNode) OpenChannel(peer LightningNode, capacity, pushAmt uint64, connect, confirm, waitForChannelActive bool) (string, error) {
// fund wallet 10*cap
_, err := n.FundWallet(uint64(1.1*float64(capacity)), true)
if err != nil {
Expand All @@ -318,6 +318,7 @@ func (n *LndNode) OpenChannel(peer LightningNode, capacity uint64, connect, conf
stream, err := n.Rpc.OpenChannel(context.Background(), &lnrpc.OpenChannelRequest{
NodePubkey: pk,
LocalFundingAmount: int64(capacity),
PushSat: int64(pushAmt),
})
if err != nil {
return "", fmt.Errorf("OpenChannel() %w", err)
Expand Down