mirror of
https://github.com/lightninglabs/loop.git
synced 2026-08-13 12:33:03 +02:00
Merge pull request #1156 from starius/lnd-21-improvements
Some checks are pending
CI / RPC compilation check (push) Waiting to run
CI / SQL compilation check (push) Waiting to run
CI / go mod check (push) Waiting to run
CI / build and lint code (push) Waiting to run
CI / verify that auto-generated documentation is up-to-date (push) Waiting to run
CI / run unit-test sqlite3 race (push) Waiting to run
CI / run unit-test postgres race (push) Waiting to run
CI / run LiT itests (push) Waiting to run
CI / run LiT unit tests (push) Waiting to run
Some checks are pending
CI / RPC compilation check (push) Waiting to run
CI / SQL compilation check (push) Waiting to run
CI / go mod check (push) Waiting to run
CI / build and lint code (push) Waiting to run
CI / verify that auto-generated documentation is up-to-date (push) Waiting to run
CI / run unit-test sqlite3 race (push) Waiting to run
CI / run unit-test postgres race (push) Waiting to run
CI / run LiT itests (push) Waiting to run
CI / run LiT unit tests (push) Waiting to run
Use new features of LND 0.21
This commit is contained in:
commit
375c02e0f6
29 changed files with 400 additions and 97 deletions
|
|
@ -55,14 +55,16 @@ linters:
|
|||
- wsl_v5
|
||||
- noinlineerr
|
||||
settings:
|
||||
staticcheck:
|
||||
checks:
|
||||
- all
|
||||
- -QF*
|
||||
- -ST*
|
||||
gosec:
|
||||
excludes:
|
||||
- G402
|
||||
- G306
|
||||
- G115
|
||||
staticcheck:
|
||||
checks:
|
||||
- -SA1019
|
||||
tagliatelle:
|
||||
case:
|
||||
rules:
|
||||
|
|
|
|||
|
|
@ -207,7 +207,7 @@ func loopIn(ctx context.Context, cmd *cli.Command) error {
|
|||
}
|
||||
|
||||
fmt.Printf("Swap initiated\n")
|
||||
fmt.Printf("ID: %v\n", resp.Id)
|
||||
fmt.Printf("ID: %x\n", resp.IdBytes)
|
||||
|
||||
if resp.HtlcAddressP2Tr != "" {
|
||||
fmt.Printf("HTLC address (P2TR): %v\n", resp.HtlcAddressP2Tr)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import (
|
|||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
|
|
@ -646,7 +645,7 @@ func getClientConn(address, tlsCertPath, macaroonPath string) (daemonConn,
|
|||
// gRPC dial options from it.
|
||||
func readMacaroon(macPath string) (grpc.DialOption, error) {
|
||||
// Load the specified macaroon file.
|
||||
macBytes, err := ioutil.ReadFile(macPath)
|
||||
macBytes, err := os.ReadFile(macPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to read macaroon path : %v", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,13 +13,11 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
defaultUtxoMinConf = 1
|
||||
)
|
||||
|
||||
var (
|
||||
defaultUtxoMinConf = 1
|
||||
channelTypeTweakless = "tweakless"
|
||||
channelTypeAnchors = "anchors"
|
||||
channelTypeSimpleTaproot = "taproot"
|
||||
channelTypeSimpleTaproot = "simple-taproot"
|
||||
channelTypeTaproot = "taproot"
|
||||
)
|
||||
|
||||
var openChannelCommand = &cli.Command{
|
||||
|
|
@ -137,9 +135,9 @@ var openChannelCommand = &cli.Command{
|
|||
&cli.StringFlag{
|
||||
Name: "channel_type",
|
||||
Usage: fmt.Sprintf("(optional) the type of channel to "+
|
||||
"propose to the remote peer (%q, %q, %q)",
|
||||
"propose to the remote peer (%q, %q, %q, %q)",
|
||||
channelTypeTweakless, channelTypeAnchors,
|
||||
channelTypeSimpleTaproot),
|
||||
channelTypeSimpleTaproot, channelTypeTaproot),
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "zero_conf",
|
||||
|
|
@ -322,6 +320,7 @@ func openChannel(ctx context.Context, cmd *cli.Command) error {
|
|||
switch channelType {
|
||||
case "":
|
||||
break
|
||||
|
||||
case channelTypeTweakless:
|
||||
req.CommitmentType = lnrpc.CommitmentType_STATIC_REMOTE_KEY
|
||||
|
||||
|
|
@ -330,6 +329,10 @@ func openChannel(ctx context.Context, cmd *cli.Command) error {
|
|||
|
||||
case channelTypeSimpleTaproot:
|
||||
req.CommitmentType = lnrpc.CommitmentType_SIMPLE_TAPROOT
|
||||
|
||||
case channelTypeTaproot:
|
||||
req.CommitmentType = lnrpc.CommitmentType_TAPROOT
|
||||
|
||||
default:
|
||||
return fmt.Errorf("unsupported channel type %v", channelType)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@
|
|||
" --max_local_csv uint (optional) the maximum number of blocks that we will allow the remote peer to require we wait before accessing our funds in the case of a unilateral close. (default: 0)\n",
|
||||
" --close_address string (optional) an address to enforce payout of our funds to on cooperative close. Note that if this value is set on channel open, you will *not* be able to cooperatively close to a different address.\n",
|
||||
" --remote_max_value_in_flight_msat uint (optional) the maximum value in msat that can be pending within the channel at any given time (default: 0)\n",
|
||||
" --channel_type string (optional) the type of channel to propose to the remote peer (\"tweakless\", \"anchors\", \"taproot\")\n",
|
||||
" --channel_type string (optional) the type of channel to propose to the remote peer (\"tweakless\", \"anchors\", \"simple-taproot\", \"taproot\")\n",
|
||||
" --zero_conf (optional) whether a zero-conf channel open should be attempted. (default: false)\n",
|
||||
" --scid_alias (optional) whether a scid-alias channel type should be negotiated. (default: false)\n",
|
||||
" --remote_reserve_sats uint (optional) the minimum number of satoshis we require the remote node to keep as a direct payment. If not specified, a default of 1% of the channel capacity will be used. (default: 0)\n",
|
||||
|
|
|
|||
104
cmd/loop/testdata/sessions/static-openchannel/07_loop-static-openchannel-taproot-success.json
vendored
Normal file
104
cmd/loop/testdata/sessions/static-openchannel/07_loop-static-openchannel-taproot-success.json
vendored
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
{
|
||||
"metadata": {
|
||||
"args": [
|
||||
"/home/user/bin/loop",
|
||||
"--rpcserver=localhost:11010",
|
||||
"--loopdir=/redacted/loop",
|
||||
"--tlscertpath=/redacted/loop/regtest/tls.cert",
|
||||
"--macaroonpath=/redacted/loop/regtest/loop.macaroon",
|
||||
"static",
|
||||
"openchannel",
|
||||
"--node_key",
|
||||
"03465f68fd39358667678f8353a31e0d99475e3fd2fb4e58daf7dbfabe04c011f4",
|
||||
"--fundmax",
|
||||
"--utxo",
|
||||
"89f6fd2ee96445c6e48278e7eaaca7de8e342904f20609ce72c0d27afb443e2d:1",
|
||||
"--channel_type",
|
||||
"taproot",
|
||||
"--private",
|
||||
"--network",
|
||||
"regtest"
|
||||
],
|
||||
"env": {},
|
||||
"version": "0.33.2-beta commit=v0.33.2-beta-bump-lnd-21-a-7-g21019e684ed06e2267382f473dfeaafb81a33310 commit_hash=21019e684ed06e2267382f473dfeaafb81a33310",
|
||||
"duration": 295879956,
|
||||
"clock_start_unix": 1782002722
|
||||
},
|
||||
"events": [
|
||||
{
|
||||
"time_ms": 2,
|
||||
"kind": "grpc",
|
||||
"data": {
|
||||
"method": "/looprpc.SwapClient/StaticOpenChannel",
|
||||
"event": "request",
|
||||
"message_type": "looprpc.StaticOpenChannelRequest",
|
||||
"payload": {
|
||||
"open_channel_request": {
|
||||
"sat_per_vbyte": "0",
|
||||
"node_pubkey": "A0ZfaP05NYZnZ4+DU6MeDZlHXj/S+05Y2vfb+r4EwBH0",
|
||||
"node_pubkey_string": "",
|
||||
"local_funding_amount": "0",
|
||||
"push_sat": "0",
|
||||
"target_conf": 0,
|
||||
"sat_per_byte": "0",
|
||||
"private": true,
|
||||
"min_htlc_msat": "0",
|
||||
"remote_csv_delay": 0,
|
||||
"min_confs": 1,
|
||||
"spend_unconfirmed": false,
|
||||
"close_address": "",
|
||||
"funding_shim": null,
|
||||
"remote_max_value_in_flight_msat": "0",
|
||||
"remote_max_htlcs": 0,
|
||||
"max_local_csv": 0,
|
||||
"commitment_type": "TAPROOT",
|
||||
"zero_conf": false,
|
||||
"scid_alias": false,
|
||||
"base_fee": "0",
|
||||
"fee_rate": "0",
|
||||
"use_base_fee": false,
|
||||
"use_fee_rate": false,
|
||||
"remote_chan_reserve_sat": "0",
|
||||
"fund_max": true,
|
||||
"memo": "",
|
||||
"outpoints": [
|
||||
{
|
||||
"txid_bytes": "",
|
||||
"txid_str": "89f6fd2ee96445c6e48278e7eaaca7de8e342904f20609ce72c0d27afb443e2d",
|
||||
"output_index": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 295,
|
||||
"kind": "grpc",
|
||||
"data": {
|
||||
"method": "/looprpc.SwapClient/StaticOpenChannel",
|
||||
"event": "response",
|
||||
"message_type": "looprpc.StaticOpenChannelResponse",
|
||||
"payload": {
|
||||
"channel_open_outpoint": "302a41b53946494306e415bdf4724e88b2cf2b37ad2f36dc075db00cc6499e9f:0"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 295,
|
||||
"kind": "stdout",
|
||||
"data": {
|
||||
"lines": [
|
||||
"{\n",
|
||||
" \"channel_open_outpoint\": \"302a41b53946494306e415bdf4724e88b2cf2b37ad2f36dc075db00cc6499e9f:0\"\n",
|
||||
"}\n"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 295,
|
||||
"kind": "exit",
|
||||
"data": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
{
|
||||
"metadata": {
|
||||
"args": [
|
||||
"/home/user/bin/loop",
|
||||
"--rpcserver=localhost:11010",
|
||||
"--loopdir=/redacted/loop",
|
||||
"--tlscertpath=/redacted/loop/regtest/tls.cert",
|
||||
"--macaroonpath=/redacted/loop/regtest/loop.macaroon",
|
||||
"static",
|
||||
"openchannel",
|
||||
"--node_key",
|
||||
"026eca9330cc3e589505c4a240ea1f7f551e5765b1aae9040c6667141da657eae6",
|
||||
"--fundmax",
|
||||
"--utxo",
|
||||
"dc942b3252ded50abc30ef4e8614d392ab0f091acab75fdd09e18a07f6ac36e6:0",
|
||||
"--channel_type",
|
||||
"taproot",
|
||||
"--private",
|
||||
"--network",
|
||||
"regtest"
|
||||
],
|
||||
"env": {},
|
||||
"version": "0.33.3-beta commit= commit_hash=",
|
||||
"run_error": "rpc error: code = Unknown desc = channel_type=taproot is not supported by the connected lnd; update LND to v0.21.0-beta or later to use this channel type: got error from server: rpc error: code = Unknown desc = unhandled request channel type 7",
|
||||
"duration": 39639744,
|
||||
"clock_start_unix": 1782158339
|
||||
},
|
||||
"events": [
|
||||
{
|
||||
"time_ms": 7,
|
||||
"kind": "grpc",
|
||||
"data": {
|
||||
"method": "/looprpc.SwapClient/StaticOpenChannel",
|
||||
"event": "request",
|
||||
"message_type": "looprpc.StaticOpenChannelRequest",
|
||||
"payload": {
|
||||
"open_channel_request": {
|
||||
"sat_per_vbyte": "0",
|
||||
"node_pubkey": "Am7KkzDMPliVBcSiQOoff1UeV2WxqukEDGZnFB2mV+rm",
|
||||
"node_pubkey_string": "",
|
||||
"local_funding_amount": "0",
|
||||
"push_sat": "0",
|
||||
"target_conf": 0,
|
||||
"sat_per_byte": "0",
|
||||
"private": true,
|
||||
"min_htlc_msat": "0",
|
||||
"remote_csv_delay": 0,
|
||||
"min_confs": 1,
|
||||
"spend_unconfirmed": false,
|
||||
"close_address": "",
|
||||
"funding_shim": null,
|
||||
"remote_max_value_in_flight_msat": "0",
|
||||
"remote_max_htlcs": 0,
|
||||
"max_local_csv": 0,
|
||||
"commitment_type": "TAPROOT",
|
||||
"zero_conf": false,
|
||||
"scid_alias": false,
|
||||
"base_fee": "0",
|
||||
"fee_rate": "0",
|
||||
"use_base_fee": false,
|
||||
"use_fee_rate": false,
|
||||
"remote_chan_reserve_sat": "0",
|
||||
"fund_max": true,
|
||||
"memo": "",
|
||||
"outpoints": [
|
||||
{
|
||||
"txid_bytes": "",
|
||||
"txid_str": "dc942b3252ded50abc30ef4e8614d392ab0f091acab75fdd09e18a07f6ac36e6",
|
||||
"output_index": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 39,
|
||||
"kind": "grpc",
|
||||
"data": {
|
||||
"method": "/looprpc.SwapClient/StaticOpenChannel",
|
||||
"event": "error",
|
||||
"error": "rpc error: code = Unknown desc = channel_type=taproot is not supported by the connected lnd; update LND to v0.21.0-beta or later to use this channel type: got error from server: rpc error: code = Unknown desc = unhandled request channel type 7",
|
||||
"status": {
|
||||
"code": 2,
|
||||
"message": "channel_type=taproot is not supported by the connected lnd; update LND to v0.21.0-beta or later to use this channel type: got error from server: rpc error: code = Unknown desc = unhandled request channel type 7"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 39,
|
||||
"kind": "stderr",
|
||||
"data": {
|
||||
"lines": [
|
||||
"[loop] rpc error: code = Unknown desc = channel_type=taproot is not supported by the connected lnd; update LND to v0.21.0-beta or later to use this channel type: got error from server: rpc error: code = Unknown desc = unhandled request channel type 7\n"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 39,
|
||||
"kind": "exit",
|
||||
"data": {
|
||||
"run_error": "rpc error: code = Unknown desc = channel_type=taproot is not supported by the connected lnd; update LND to v0.21.0-beta or later to use this channel type: got error from server: rpc error: code = Unknown desc = unhandled request channel type 7"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -142,6 +142,7 @@ func MigrateLoopOutCosts(ctx context.Context, lnd lndclient.LndServices,
|
|||
ctx, lndclient.ListPaymentsRequest{
|
||||
Offset: offset,
|
||||
MaxPayments: uint64(paymentBatchSize),
|
||||
OmitHops: true,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -163,6 +163,11 @@ func TestCostMigration(t *testing.T) {
|
|||
// Now we can run the migration.
|
||||
err = MigrateLoopOutCosts(context.Background(), lnd.LndServices, 1, store)
|
||||
require.NoError(t, err)
|
||||
listPaymentsRequests := lnd.ListPaymentsRequestsSnapshot()
|
||||
require.NotEmpty(t, listPaymentsRequests)
|
||||
for _, req := range listPaymentsRequests {
|
||||
require.True(t, req.OmitHops)
|
||||
}
|
||||
|
||||
// Finally check that the swap cost has been updated correctly.
|
||||
swap, err := store.FetchLoopOutSwap(
|
||||
|
|
|
|||
|
|
@ -589,7 +589,7 @@ Open a channel to an existing peer.
|
|||
\fB--base_fee_msat\fP="": the base fee in milli-satoshis that will be charged for each forwarded HTLC, regardless of payment size (default: 0)
|
||||
|
||||
.PP
|
||||
\fB--channel_type\fP="": (optional) the type of channel to propose to the remote peer ("tweakless", "anchors", "taproot")
|
||||
\fB--channel_type\fP="": (optional) the type of channel to propose to the remote peer ("tweakless", "anchors", "simple-taproot", "taproot")
|
||||
|
||||
.PP
|
||||
\fB--close_address\fP="": (optional) an address to enforce payout of our funds to on cooperative close. Note that if this value is set on channel open, you will \fInot\fP be able to cooperatively close to a different address.
|
||||
|
|
|
|||
|
|
@ -715,7 +715,7 @@ The following flags are supported:
|
|||
| `--max_local_csv="…"` | (optional) the maximum number of blocks that we will allow the remote peer to require we wait before accessing our funds in the case of a unilateral close | uint | `0` |
|
||||
| `--close_address="…"` | (optional) an address to enforce payout of our funds to on cooperative close. Note that if this value is set on channel open, you will *not* be able to cooperatively close to a different address | string |
|
||||
| `--remote_max_value_in_flight_msat="…"` | (optional) the maximum value in msat that can be pending within the channel at any given time | uint | `0` |
|
||||
| `--channel_type="…"` | (optional) the type of channel to propose to the remote peer ("tweakless", "anchors", "taproot") | string |
|
||||
| `--channel_type="…"` | (optional) the type of channel to propose to the remote peer ("tweakless", "anchors", "simple-taproot", "taproot") | string |
|
||||
| `--zero_conf` | (optional) whether a zero-conf channel open should be attempted | bool | `false` |
|
||||
| `--scid_alias` | (optional) whether a scid-alias channel type should be negotiated | bool | `false` |
|
||||
| `--remote_reserve_sats="…"` | (optional) the minimum number of satoshis we require the remote node to keep as a direct payment. If not specified, a default of 1% of the channel capacity will be used | uint | `0` |
|
||||
|
|
|
|||
2
go.mod
2
go.mod
|
|
@ -20,7 +20,7 @@ require (
|
|||
github.com/jessevdk/go-flags v1.6.1
|
||||
github.com/lib/pq v1.10.9
|
||||
github.com/lightninglabs/aperture v0.4.0
|
||||
github.com/lightninglabs/lndclient v0.21.0-1
|
||||
github.com/lightninglabs/lndclient v0.21.0-2
|
||||
github.com/lightninglabs/loop/looprpc v1.0.7
|
||||
github.com/lightninglabs/loop/swapserverrpc v1.0.14
|
||||
github.com/lightninglabs/taproot-assets v0.8.0
|
||||
|
|
|
|||
4
go.sum
4
go.sum
|
|
@ -1116,8 +1116,8 @@ github.com/lightninglabs/gozmq v0.0.0-20191113021534-d20a764486bf h1:HZKvJUHlcXI
|
|||
github.com/lightninglabs/gozmq v0.0.0-20191113021534-d20a764486bf/go.mod h1:vxmQPeIQxPf6Jf9rM8R+B4rKBqLA2AjttNxkFBL2Plk=
|
||||
github.com/lightninglabs/lightning-node-connect/hashmailrpc v1.0.4-0.20250610182311-2f1d46ef18b7 h1:373o5lNr1udAdhcf5+zq/0dYpRtkvYLl8Lk6wG7I0DY=
|
||||
github.com/lightninglabs/lightning-node-connect/hashmailrpc v1.0.4-0.20250610182311-2f1d46ef18b7/go.mod h1:bDnEKRN1u13NFBuy/C+bFLhxA5bfd3clT25y76QY0AM=
|
||||
github.com/lightninglabs/lndclient v0.21.0-1 h1:NuyccCK7tbMaH7hhqtewcx+qeBel4/RLJrlnQ/lMkkY=
|
||||
github.com/lightninglabs/lndclient v0.21.0-1/go.mod h1:RUIcfPr82HrvZr3pu9f8nbD5v6VFbm+KgExqNNp5bE4=
|
||||
github.com/lightninglabs/lndclient v0.21.0-2 h1:gA1utFMoKV6OZfHpYAQ1TX0wVs5cAtgTORRVavHR/ls=
|
||||
github.com/lightninglabs/lndclient v0.21.0-2/go.mod h1:RUIcfPr82HrvZr3pu9f8nbD5v6VFbm+KgExqNNp5bE4=
|
||||
github.com/lightninglabs/migrate/v4 v4.18.2-9023d66a-fork-pr-2.0.20251211093704-71c1eef09789 h1:7kX7vUgHUazAHcCJ6uzBDa4/2MEGEbMEfa01GtfqmTQ=
|
||||
github.com/lightninglabs/migrate/v4 v4.18.2-9023d66a-fork-pr-2.0.20251211093704-71c1eef09789/go.mod h1:99BKpIi6ruaaXRM1A77eqZ+FWPQ3cfRa+ZVy5bmWMaY=
|
||||
github.com/lightninglabs/neutrino v0.17.1 h1:lNhgq7ix/N81R6oATroP/kHMzH1qzVVF2dEGcTlN2t4=
|
||||
|
|
|
|||
|
|
@ -559,8 +559,11 @@ func RpcToParameters(req *clientrpc.LiquidityParameters) (*Parameters,
|
|||
req.AutoloopBudgetSat != 0 {
|
||||
|
||||
params.AutoFeeRefreshPeriod = InfiniteDuration
|
||||
// Keep reading the legacy start field so old stored
|
||||
// liquidity parameters migrate to the refresh-period model.
|
||||
budgetStartSec := req.AutoloopBudgetStartSec //nolint:staticcheck
|
||||
params.AutoloopBudgetLastRefresh = time.Unix(
|
||||
int64(req.AutoloopBudgetStartSec), 0)
|
||||
int64(budgetStartSec), 0)
|
||||
}
|
||||
|
||||
for _, rule := range req.Rules {
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ import (
|
|||
"github.com/lightningnetwork/lnd/clock"
|
||||
"github.com/lightningnetwork/lnd/lntypes"
|
||||
"github.com/lightningnetwork/lnd/macaroons"
|
||||
"go.etcd.io/bbolt"
|
||||
bbolterrors "go.etcd.io/bbolt/errors"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
"gopkg.in/macaroon-bakery.v2/bakery"
|
||||
|
|
@ -161,7 +161,7 @@ func (d *Daemon) Start() error {
|
|||
// and error handlers. If this fails, then nothing has been started yet,
|
||||
// and we can just return the error.
|
||||
err = d.initialize(true)
|
||||
if errors.Is(err, bbolt.ErrTimeout) {
|
||||
if errors.Is(err, bbolterrors.ErrTimeout) {
|
||||
// We're trying to be started as a standalone Loop daemon, most
|
||||
// likely LiT is already running and blocking the DB
|
||||
return fmt.Errorf("%v: make sure no other loop daemon process "+
|
||||
|
|
@ -211,7 +211,7 @@ func (d *Daemon) StartAsSubserver(lndGrpc *lndclient.GrpcLndServices,
|
|||
// handlers. If this fails, then nothing has been started yet, and we
|
||||
// can just return the error.
|
||||
err := d.initialize(withMacaroonService)
|
||||
if errors.Is(err, bbolt.ErrTimeout) {
|
||||
if errors.Is(err, bbolterrors.ErrTimeout) {
|
||||
// We're trying to be started inside LiT so there most likely is
|
||||
// another standalone Loop process blocking the DB.
|
||||
return fmt.Errorf("%v: make sure no other loop daemon "+
|
||||
|
|
@ -994,7 +994,7 @@ func (d *Daemon) initialize(withMacaroonService bool) error {
|
|||
d.wg.Go(func() {
|
||||
infof("Starting static address open channel manager")
|
||||
err := openChannelManager.Run(d.mainCtx)
|
||||
if err != nil && !errors.Is(context.Canceled, err) {
|
||||
if err != nil && !errors.Is(err, context.Canceled) {
|
||||
d.internalErrChan <- err
|
||||
}
|
||||
infof("Static address open channel manager stopped")
|
||||
|
|
|
|||
|
|
@ -251,6 +251,7 @@ func (s *swapClientServer) LoopOut(ctx context.Context,
|
|||
req.AssetSwapRfqId = in.AssetRfqInfo.SwapRfqId
|
||||
}
|
||||
|
||||
// Keep accepting the deprecated single-channel field for older clients.
|
||||
switch {
|
||||
case in.LoopOutChannel != 0 && len(in.OutgoingChanSet) > 0: // nolint:staticcheck
|
||||
return nil, errors.New("loop_out_channel and outgoing_" +
|
||||
|
|
@ -273,7 +274,7 @@ func (s *swapClientServer) LoopOut(ctx context.Context,
|
|||
resp := &looprpc.SwapResponse{
|
||||
Id: info.SwapHash.String(),
|
||||
IdBytes: info.SwapHash[:],
|
||||
HtlcAddress: htlcAddress,
|
||||
HtlcAddress: htlcAddress, //nolint:staticcheck
|
||||
ServerMessage: info.ServerMessage,
|
||||
}
|
||||
|
||||
|
|
@ -1182,11 +1183,11 @@ func (s *swapClientServer) LoopIn(ctx context.Context,
|
|||
|
||||
if loopdb.CurrentProtocolVersion() < loopdb.ProtocolVersionHtlcV3 {
|
||||
p2wshAddr := swapInfo.HtlcAddressP2WSH.String()
|
||||
response.HtlcAddress = p2wshAddr
|
||||
response.HtlcAddress = p2wshAddr //nolint:staticcheck
|
||||
response.HtlcAddressP2Wsh = p2wshAddr
|
||||
} else {
|
||||
p2trAddr := swapInfo.HtlcAddressP2TR.String()
|
||||
response.HtlcAddress = p2trAddr
|
||||
response.HtlcAddress = p2trAddr //nolint:staticcheck
|
||||
response.HtlcAddressP2Tr = p2trAddr
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@ package loopdb
|
|||
|
||||
import (
|
||||
"context"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
|
|
@ -48,9 +46,7 @@ func TestMigrationUpdates(t *testing.T) {
|
|||
ctxb := context.Background()
|
||||
|
||||
// Restore a legacy database.
|
||||
tempDirName, err := ioutil.TempDir("", "clientstore")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tempDirName)
|
||||
tempDirName := t.TempDir()
|
||||
|
||||
tempPath := filepath.Join(tempDirName, dbFileName)
|
||||
db, err := bbolt.Open(tempPath, 0600, nil)
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import (
|
|||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"github.com/lightningnetwork/lnd/lntypes"
|
||||
"go.etcd.io/bbolt"
|
||||
bbolterrors "go.etcd.io/bbolt/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -197,9 +198,9 @@ func NewBoltSwapStore(dbPath string, chainParams *chaincfg.Params) (
|
|||
bdb, err := bboltOpen(path, 0600, &bbolt.Options{
|
||||
Timeout: DefaultLoopDBTimeout,
|
||||
})
|
||||
if errors.Is(err, bbolt.ErrTimeout) {
|
||||
if errors.Is(err, bbolterrors.ErrTimeout) {
|
||||
return nil, fmt.Errorf("%w: couldn't obtain exclusive lock on "+
|
||||
"%s, timed out after %v", bbolt.ErrTimeout, path,
|
||||
"%s, timed out after %v", bbolterrors.ErrTimeout, path,
|
||||
DefaultLoopDBTimeout)
|
||||
}
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import (
|
|||
"context"
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
|
@ -18,6 +17,7 @@ import (
|
|||
"github.com/lightningnetwork/lnd/routing/route"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.etcd.io/bbolt"
|
||||
bbolterrors "go.etcd.io/bbolt/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -62,7 +62,7 @@ func TestNewBoltSwapStoreTimeout(t *testing.T) {
|
|||
bboltOpen = origOpen
|
||||
})
|
||||
|
||||
wrappedErr := fmt.Errorf("wrapped: %w", bbolt.ErrTimeout)
|
||||
wrappedErr := fmt.Errorf("wrapped: %w", bbolterrors.ErrTimeout)
|
||||
bboltOpen = func(path string, mode os.FileMode,
|
||||
options *bbolt.Options) (*bbolt.DB, error) {
|
||||
|
||||
|
|
@ -74,7 +74,7 @@ func TestNewBoltSwapStoreTimeout(t *testing.T) {
|
|||
|
||||
store, err := NewBoltSwapStore(tempDir, &chaincfg.MainNetParams)
|
||||
require.Nil(t, store)
|
||||
require.ErrorIs(t, err, bbolt.ErrTimeout)
|
||||
require.ErrorIs(t, err, bbolterrors.ErrTimeout)
|
||||
require.ErrorContains(t, err, "couldn't obtain exclusive lock")
|
||||
}
|
||||
|
||||
|
|
@ -142,10 +142,7 @@ func TestLoopOutStore(t *testing.T) {
|
|||
// testLoopOutStore tests the basic functionality of the current bbolt
|
||||
// swap store for specific swap parameters.
|
||||
func testLoopOutStore(t *testing.T, pendingSwap *LoopOutContract) {
|
||||
tempDirName, err := ioutil.TempDir("", "clientstore")
|
||||
require.NoError(t, err)
|
||||
|
||||
defer os.RemoveAll(tempDirName)
|
||||
tempDirName := t.TempDir()
|
||||
|
||||
store, err := NewBoltSwapStore(tempDirName, &chaincfg.MainNetParams)
|
||||
require.NoError(t, err)
|
||||
|
|
@ -284,9 +281,7 @@ func TestLoopInStore(t *testing.T) {
|
|||
}
|
||||
|
||||
func testLoopInStore(t *testing.T, pendingSwap LoopInContract) {
|
||||
tempDirName, err := ioutil.TempDir("", "clientstore")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tempDirName)
|
||||
tempDirName := t.TempDir()
|
||||
|
||||
store, err := NewBoltSwapStore(tempDirName, &chaincfg.MainNetParams)
|
||||
require.NoError(t, err)
|
||||
|
|
@ -366,11 +361,7 @@ func testLoopInStore(t *testing.T, pendingSwap LoopInContract) {
|
|||
// TestVersionNew tests that a new database is initialized with the current
|
||||
// version.
|
||||
func TestVersionNew(t *testing.T) {
|
||||
tempDirName, err := ioutil.TempDir("", "clientstore")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(tempDirName)
|
||||
tempDirName := t.TempDir()
|
||||
|
||||
store, err := NewBoltSwapStore(tempDirName, &chaincfg.MainNetParams)
|
||||
if err != nil {
|
||||
|
|
@ -390,11 +381,7 @@ func TestVersionNew(t *testing.T) {
|
|||
// TestVersionMigrated tests that an existing version zero database is migrated
|
||||
// to the latest version.
|
||||
func TestVersionMigrated(t *testing.T) {
|
||||
tempDirName, err := ioutil.TempDir("", "clientstore")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(tempDirName)
|
||||
tempDirName := t.TempDir()
|
||||
|
||||
createVersionZeroDb(t, tempDirName)
|
||||
|
||||
|
|
@ -459,11 +446,7 @@ func TestLegacyOutgoingChannel(t *testing.T) {
|
|||
}
|
||||
|
||||
// Restore a legacy database.
|
||||
tempDirName, err := ioutil.TempDir("", "clientstore")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(tempDirName)
|
||||
tempDirName := t.TempDir()
|
||||
|
||||
tempPath := filepath.Join(tempDirName, dbFileName)
|
||||
db, err := bbolt.Open(tempPath, 0600, nil)
|
||||
|
|
@ -498,9 +481,7 @@ func TestLegacyOutgoingChannel(t *testing.T) {
|
|||
// TestLiquidityParams checks that reading and writing to liquidty bucket are
|
||||
// as expected.
|
||||
func TestLiquidityParams(t *testing.T) {
|
||||
tempDirName, err := ioutil.TempDir("", "clientstore")
|
||||
require.NoError(t, err, "failed to db")
|
||||
defer os.RemoveAll(tempDirName)
|
||||
tempDirName := t.TempDir()
|
||||
|
||||
ctxb := context.Background()
|
||||
|
||||
|
|
|
|||
|
|
@ -66,6 +66,10 @@ func (m *mockStaticAddressClient) PushStaticAddressHtlcSigs(ctx context.Context,
|
|||
args.Error(1)
|
||||
}
|
||||
|
||||
// ServerWithdrawDeposits implements the deprecated RPC required by the
|
||||
// generated client interface. Production code uses ServerPsbtWithdrawDeposits.
|
||||
//
|
||||
//nolint:staticcheck
|
||||
func (m *mockStaticAddressClient) ServerWithdrawDeposits(ctx context.Context,
|
||||
in *swapserverrpc.ServerWithdrawRequest,
|
||||
opts ...grpc.CallOption) (*swapserverrpc.ServerWithdrawResponse,
|
||||
|
|
|
|||
|
|
@ -71,6 +71,10 @@ func (m *mockStaticAddressClient) PushStaticAddressHtlcSigs(ctx context.Context,
|
|||
args.Error(1)
|
||||
}
|
||||
|
||||
// ServerWithdrawDeposits implements the deprecated RPC required by the
|
||||
// generated client interface. Production code uses ServerPsbtWithdrawDeposits.
|
||||
//
|
||||
//nolint:staticcheck
|
||||
func (m *mockStaticAddressClient) ServerWithdrawDeposits(ctx context.Context,
|
||||
in *swapserverrpc.ServerWithdrawRequest,
|
||||
opts ...grpc.CallOption) (*swapserverrpc.ServerWithdrawResponse,
|
||||
|
|
|
|||
|
|
@ -310,6 +310,8 @@ func (m *Manager) OpenChannel(ctx context.Context,
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// If a local funding amount is set, coin-select deposits to
|
||||
// cover it. Otherwise fundmax uses all available deposits.
|
||||
if req.LocalFundingAmount != 0 {
|
||||
deposits, err = staticutil.SelectDeposits(
|
||||
deposits, req.LocalFundingAmount,
|
||||
|
|
@ -319,9 +321,6 @@ func (m *Manager) OpenChannel(ctx context.Context,
|
|||
return nil, fmt.Errorf("error selecting "+
|
||||
"deposits: %w", err)
|
||||
}
|
||||
} else {
|
||||
// The fundmax flag is set, hence we select all deposits
|
||||
// for funding the channel.
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -369,6 +368,7 @@ func (m *Manager) OpenChannel(ctx context.Context,
|
|||
if err == nil {
|
||||
return chanOutpoint, nil
|
||||
}
|
||||
err = maybeWrapTaprootUnsupportedError(reqClone, err)
|
||||
|
||||
log.Infof("error opening channel: %v", err)
|
||||
|
||||
|
|
@ -773,6 +773,9 @@ func resolveCommitmentType(commitmentType lnrpc.CommitmentType) (
|
|||
case lnrpc.CommitmentType_SIMPLE_TAPROOT:
|
||||
return lnrpc.CommitmentType_SIMPLE_TAPROOT, nil
|
||||
|
||||
case lnrpc.CommitmentType_TAPROOT:
|
||||
return lnrpc.CommitmentType_TAPROOT, nil
|
||||
|
||||
default:
|
||||
return lnrpc.CommitmentType_UNKNOWN_COMMITMENT_TYPE, fmt.Errorf(
|
||||
"unsupported commitment type %v", commitmentType,
|
||||
|
|
@ -780,6 +783,30 @@ func resolveCommitmentType(commitmentType lnrpc.CommitmentType) (
|
|||
}
|
||||
}
|
||||
|
||||
// maybeWrapTaprootUnsupportedError turns lnd's generic unknown channel type
|
||||
// error into a user-actionable message for Loop's production taproot channel
|
||||
// type.
|
||||
func maybeWrapTaprootUnsupportedError(req *lnrpc.OpenChannelRequest,
|
||||
err error) error {
|
||||
|
||||
if err == nil || req.CommitmentType != lnrpc.CommitmentType_TAPROOT {
|
||||
return err
|
||||
}
|
||||
|
||||
errMsg := strings.ToLower(err.Error())
|
||||
switch {
|
||||
case strings.Contains(errMsg, "unhandled request channel type"),
|
||||
strings.Contains(errMsg, "unknown channel type"),
|
||||
strings.Contains(errMsg, "unsupported channel type"):
|
||||
|
||||
return fmt.Errorf("channel_type=taproot is not supported "+
|
||||
"by the connected lnd; update LND to v0.21.0-beta "+
|
||||
"or later to use this channel type: %w", err)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// checkPsbtFlags make sure a request to open a channel doesn't set any
|
||||
// parameters that are incompatible with the PSBT funding flow.
|
||||
func checkPsbtFlags(req *lnrpc.OpenChannelRequest) error {
|
||||
|
|
|
|||
|
|
@ -573,6 +573,11 @@ func TestResolveCommitmentType(t *testing.T) {
|
|||
commitmentType: lnrpc.CommitmentType_SIMPLE_TAPROOT,
|
||||
expectedType: lnrpc.CommitmentType_SIMPLE_TAPROOT,
|
||||
},
|
||||
{
|
||||
name: "production taproot supported",
|
||||
commitmentType: lnrpc.CommitmentType_TAPROOT,
|
||||
expectedType: lnrpc.CommitmentType_TAPROOT,
|
||||
},
|
||||
{
|
||||
name: "legacy rejected",
|
||||
commitmentType: lnrpc.CommitmentType_LEGACY,
|
||||
|
|
@ -596,6 +601,33 @@ func TestResolveCommitmentType(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// TestMaybeWrapTaprootUnsupportedError verifies that generic old-lnd channel
|
||||
// type rejections become actionable for Loop users selecting production
|
||||
// taproot channels.
|
||||
func TestMaybeWrapTaprootUnsupportedError(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
baseErr := errors.New("got error from server: rpc error: " +
|
||||
"code = Unknown desc = unhandled request channel type 7")
|
||||
req := &lnrpc.OpenChannelRequest{
|
||||
CommitmentType: lnrpc.CommitmentType_TAPROOT,
|
||||
}
|
||||
|
||||
err := maybeWrapTaprootUnsupportedError(req, baseErr)
|
||||
require.ErrorContains(
|
||||
t, err, "channel_type=taproot is not supported",
|
||||
)
|
||||
require.ErrorContains(
|
||||
t, err, "update LND to v0.21.0-beta or later",
|
||||
)
|
||||
require.ErrorIs(t, err, baseErr)
|
||||
|
||||
req.CommitmentType = lnrpc.CommitmentType_SIMPLE_TAPROOT
|
||||
err = maybeWrapTaprootUnsupportedError(req, baseErr)
|
||||
require.ErrorIs(t, err, baseErr)
|
||||
require.NotContains(t, err.Error(), "update LND")
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Mock types for PSBT channel open flow tests.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -232,8 +232,10 @@ func estimateFee(numInputs int, feeRate chainfee.SatPerKWeight,
|
|||
|
||||
// Add the funding output based on commitment type.
|
||||
switch commitmentType {
|
||||
case lnrpc.CommitmentType_SIMPLE_TAPROOT:
|
||||
case lnrpc.CommitmentType_SIMPLE_TAPROOT,
|
||||
lnrpc.CommitmentType_TAPROOT:
|
||||
we.AddP2TROutput()
|
||||
|
||||
default:
|
||||
we.AddP2WSHOutput()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -271,9 +271,6 @@ func TestSelectDeposits(t *testing.T) {
|
|||
// High fee rate: 100 sat/vbyte = 25000 sat/kw.
|
||||
highFeeRate := chainfee.SatPerKVByte(100_000).FeePerKWeight()
|
||||
|
||||
anchors := lnrpc.CommitmentType_ANCHORS
|
||||
taproot := lnrpc.CommitmentType_SIMPLE_TAPROOT
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
deposits []*deposit.Deposit
|
||||
|
|
@ -290,7 +287,7 @@ func TestSelectDeposits(t *testing.T) {
|
|||
deposits: makeDeposits(1_000, 2_000),
|
||||
amount: 1_000_000,
|
||||
feeRate: lowFeeRate,
|
||||
commitmentType: anchors,
|
||||
commitmentType: lnrpc.CommitmentType_ANCHORS,
|
||||
wantErr: "insufficient funds",
|
||||
},
|
||||
{
|
||||
|
|
@ -298,7 +295,7 @@ func TestSelectDeposits(t *testing.T) {
|
|||
deposits: makeDeposits(100_000),
|
||||
amount: 100_000,
|
||||
feeRate: lowFeeRate,
|
||||
commitmentType: anchors,
|
||||
commitmentType: lnrpc.CommitmentType_ANCHORS,
|
||||
wantErr: "insufficient funds",
|
||||
},
|
||||
{
|
||||
|
|
@ -310,7 +307,7 @@ func TestSelectDeposits(t *testing.T) {
|
|||
deposits: makeDeposits(51_000),
|
||||
amount: 50_000,
|
||||
feeRate: highFeeRate,
|
||||
commitmentType: anchors,
|
||||
commitmentType: lnrpc.CommitmentType_ANCHORS,
|
||||
wantErr: "insufficient funds",
|
||||
},
|
||||
{
|
||||
|
|
@ -327,7 +324,7 @@ func TestSelectDeposits(t *testing.T) {
|
|||
),
|
||||
amount: 400_000,
|
||||
feeRate: highFeeRate,
|
||||
commitmentType: anchors,
|
||||
commitmentType: lnrpc.CommitmentType_ANCHORS,
|
||||
wantCount: 2,
|
||||
validate: func(t *testing.T, selected []*deposit.Deposit) {
|
||||
require.Equal(
|
||||
|
|
@ -345,7 +342,7 @@ func TestSelectDeposits(t *testing.T) {
|
|||
deposits: makeDeposits(500_000),
|
||||
amount: 100_000,
|
||||
feeRate: lowFeeRate,
|
||||
commitmentType: anchors,
|
||||
commitmentType: lnrpc.CommitmentType_ANCHORS,
|
||||
wantCount: 1,
|
||||
},
|
||||
{
|
||||
|
|
@ -353,7 +350,7 @@ func TestSelectDeposits(t *testing.T) {
|
|||
deposits: makeDeposits(60_000, 60_000),
|
||||
amount: 100_000,
|
||||
feeRate: lowFeeRate,
|
||||
commitmentType: anchors,
|
||||
commitmentType: lnrpc.CommitmentType_ANCHORS,
|
||||
wantCount: 2,
|
||||
},
|
||||
{
|
||||
|
|
@ -361,7 +358,7 @@ func TestSelectDeposits(t *testing.T) {
|
|||
deposits: makeDeposits(10_000, 200_000, 50_000),
|
||||
amount: 100_000,
|
||||
feeRate: lowFeeRate,
|
||||
commitmentType: anchors,
|
||||
commitmentType: lnrpc.CommitmentType_ANCHORS,
|
||||
wantCount: 1,
|
||||
validate: func(t *testing.T, selected []*deposit.Deposit) {
|
||||
// Should pick the 200k deposit.
|
||||
|
|
@ -388,13 +385,13 @@ func TestSelectDeposits(t *testing.T) {
|
|||
deposits: makeDeposits(35_500, 35_500, 10_000),
|
||||
amount: 50_000,
|
||||
feeRate: highFeeRate,
|
||||
commitmentType: anchors,
|
||||
commitmentType: lnrpc.CommitmentType_ANCHORS,
|
||||
wantCount: 3,
|
||||
validate: func(t *testing.T, selected []*deposit.Deposit) {
|
||||
total := depositSum(selected)
|
||||
fee := estimateFee(
|
||||
len(selected), highFeeRate,
|
||||
anchors,
|
||||
lnrpc.CommitmentType_ANCHORS,
|
||||
)
|
||||
require.GreaterOrEqual(
|
||||
t, total,
|
||||
|
|
@ -407,7 +404,7 @@ func TestSelectDeposits(t *testing.T) {
|
|||
deposits: makeDeposits(40_000, 40_000, 40_000),
|
||||
amount: 100_000,
|
||||
feeRate: lowFeeRate,
|
||||
commitmentType: anchors,
|
||||
commitmentType: lnrpc.CommitmentType_ANCHORS,
|
||||
wantCount: 3,
|
||||
},
|
||||
{
|
||||
|
|
@ -415,7 +412,7 @@ func TestSelectDeposits(t *testing.T) {
|
|||
deposits: makeDeposits(100_000, 50_000),
|
||||
amount: 99_000,
|
||||
feeRate: 0,
|
||||
commitmentType: anchors,
|
||||
commitmentType: lnrpc.CommitmentType_ANCHORS,
|
||||
wantCount: 1,
|
||||
validate: func(t *testing.T, selected []*deposit.Deposit) {
|
||||
// With zero fee, 100k covers 99k + 0 + dust.
|
||||
|
|
@ -430,12 +427,12 @@ func TestSelectDeposits(t *testing.T) {
|
|||
deposits: makeDeposits(200_000, 100_000, 50_000),
|
||||
amount: 100_000,
|
||||
feeRate: highFeeRate,
|
||||
commitmentType: anchors,
|
||||
commitmentType: lnrpc.CommitmentType_ANCHORS,
|
||||
validate: func(t *testing.T, selected []*deposit.Deposit) {
|
||||
total := depositSum(selected)
|
||||
fee := estimateFee(
|
||||
len(selected), highFeeRate,
|
||||
anchors,
|
||||
lnrpc.CommitmentType_ANCHORS,
|
||||
)
|
||||
require.GreaterOrEqual(
|
||||
t, total,
|
||||
|
|
@ -448,7 +445,15 @@ func TestSelectDeposits(t *testing.T) {
|
|||
deposits: makeDeposits(500_000),
|
||||
amount: 100_000,
|
||||
feeRate: lowFeeRate,
|
||||
commitmentType: taproot,
|
||||
commitmentType: lnrpc.CommitmentType_SIMPLE_TAPROOT,
|
||||
wantCount: 1,
|
||||
},
|
||||
{
|
||||
name: "production taproot commitment type",
|
||||
deposits: makeDeposits(500_000),
|
||||
amount: 100_000,
|
||||
feeRate: lowFeeRate,
|
||||
commitmentType: lnrpc.CommitmentType_TAPROOT,
|
||||
wantCount: 1,
|
||||
},
|
||||
{
|
||||
|
|
@ -459,12 +464,12 @@ func TestSelectDeposits(t *testing.T) {
|
|||
),
|
||||
amount: 50_000,
|
||||
feeRate: lowFeeRate,
|
||||
commitmentType: anchors,
|
||||
commitmentType: lnrpc.CommitmentType_ANCHORS,
|
||||
validate: func(t *testing.T, selected []*deposit.Deposit) {
|
||||
total := depositSum(selected)
|
||||
fee := estimateFee(
|
||||
len(selected), lowFeeRate,
|
||||
anchors,
|
||||
lnrpc.CommitmentType_ANCHORS,
|
||||
)
|
||||
require.GreaterOrEqual(
|
||||
t, total,
|
||||
|
|
@ -484,12 +489,12 @@ func TestSelectDeposits(t *testing.T) {
|
|||
),
|
||||
amount: 150_000,
|
||||
feeRate: lowFeeRate,
|
||||
commitmentType: anchors,
|
||||
commitmentType: lnrpc.CommitmentType_ANCHORS,
|
||||
validate: func(t *testing.T, selected []*deposit.Deposit) {
|
||||
total := depositSum(selected)
|
||||
fee := estimateFee(
|
||||
len(selected), lowFeeRate,
|
||||
anchors,
|
||||
lnrpc.CommitmentType_ANCHORS,
|
||||
)
|
||||
// Core invariant: selected amount covers
|
||||
// requested amount + fee + dust.
|
||||
|
|
@ -506,7 +511,7 @@ func TestSelectDeposits(t *testing.T) {
|
|||
deposits: makeDeposits(10_000, 20_000, 300_000),
|
||||
amount: 100_000,
|
||||
feeRate: lowFeeRate,
|
||||
commitmentType: anchors,
|
||||
commitmentType: lnrpc.CommitmentType_ANCHORS,
|
||||
wantCount: 1,
|
||||
validate: func(t *testing.T, selected []*deposit.Deposit) {
|
||||
require.Equal(
|
||||
|
|
@ -525,7 +530,7 @@ func TestSelectDeposits(t *testing.T) {
|
|||
deposits: makeDeposits(60_000, 60_000),
|
||||
amount: 50_000,
|
||||
feeRate: highFeeRate,
|
||||
commitmentType: anchors,
|
||||
commitmentType: lnrpc.CommitmentType_ANCHORS,
|
||||
wantCount: 2,
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -235,6 +235,11 @@ func TestCalculateWithdrawalTxValuesCommitmentTypeParity(t *testing.T) {
|
|||
commitmentType: lnrpc.CommitmentType_SIMPLE_TAPROOT,
|
||||
addr: taprootAddr,
|
||||
},
|
||||
{
|
||||
name: "production taproot and p2tr",
|
||||
commitmentType: lnrpc.CommitmentType_TAPROOT,
|
||||
addr: taprootAddr,
|
||||
},
|
||||
}
|
||||
|
||||
selectedAmounts := []btcutil.Amount{
|
||||
|
|
|
|||
|
|
@ -1108,7 +1108,8 @@ func WithdrawalTxWeight(numInputs int, sweepAddress btcutil.Address,
|
|||
|
||||
if commitmentType != lnrpc.CommitmentType_UNKNOWN_COMMITMENT_TYPE {
|
||||
switch commitmentType {
|
||||
case lnrpc.CommitmentType_SIMPLE_TAPROOT:
|
||||
case lnrpc.CommitmentType_SIMPLE_TAPROOT,
|
||||
lnrpc.CommitmentType_TAPROOT:
|
||||
weightEstimator.AddP2TROutput()
|
||||
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -266,6 +266,11 @@ func (h *mockLightningClient) ListPayments(_ context.Context,
|
|||
req lndclient.ListPaymentsRequest) (*lndclient.ListPaymentsResponse,
|
||||
error) {
|
||||
|
||||
h.lnd.lock.Lock()
|
||||
defer h.lnd.lock.Unlock()
|
||||
|
||||
h.lnd.ListPaymentsRequests = append(h.lnd.ListPaymentsRequests, req)
|
||||
|
||||
if req.Offset >= uint64(len(h.lnd.Payments)) {
|
||||
return &lndclient.ListPaymentsResponse{}, nil
|
||||
}
|
||||
|
|
@ -273,7 +278,8 @@ func (h *mockLightningClient) ListPayments(_ context.Context,
|
|||
lastIndexOffset := req.Offset + req.MaxPayments
|
||||
lastIndexOffset = min(lastIndexOffset, uint64(len(h.lnd.Payments)))
|
||||
|
||||
result := h.lnd.Payments[req.Offset:lastIndexOffset]
|
||||
result := make([]lndclient.Payment, lastIndexOffset-req.Offset)
|
||||
copy(result, h.lnd.Payments[req.Offset:lastIndexOffset])
|
||||
|
||||
return &lndclient.ListPaymentsResponse{
|
||||
Payments: result,
|
||||
|
|
|
|||
|
|
@ -162,12 +162,13 @@ type LndMockServices struct {
|
|||
// keyed by hash string.
|
||||
Invoices map[lntypes.Hash]*lndclient.Invoice
|
||||
|
||||
Channels []lndclient.ChannelInfo
|
||||
ChannelEdges map[uint64]*lndclient.ChannelEdge
|
||||
ClosedChannels []lndclient.ClosedChannel
|
||||
ForwardingEvents []lndclient.ForwardingEvent
|
||||
Payments []lndclient.Payment
|
||||
MissionControlState []lndclient.MissionControlEntry
|
||||
Channels []lndclient.ChannelInfo
|
||||
ChannelEdges map[uint64]*lndclient.ChannelEdge
|
||||
ClosedChannels []lndclient.ClosedChannel
|
||||
ForwardingEvents []lndclient.ForwardingEvent
|
||||
Payments []lndclient.Payment
|
||||
ListPaymentsRequests []lndclient.ListPaymentsRequest
|
||||
MissionControlState []lndclient.MissionControlEntry
|
||||
|
||||
WaitForFinished func()
|
||||
|
||||
|
|
@ -185,6 +186,20 @@ func (s *LndMockServices) EpochSubscribers() int32 {
|
|||
return int32(len(s.blockHeightListeners))
|
||||
}
|
||||
|
||||
// ListPaymentsRequestsSnapshot returns a copy of all ListPayments requests
|
||||
// recorded by the mock.
|
||||
func (s *LndMockServices) ListPaymentsRequestsSnapshot() []lndclient.ListPaymentsRequest {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
|
||||
requests := make(
|
||||
[]lndclient.ListPaymentsRequest, len(s.ListPaymentsRequests),
|
||||
)
|
||||
copy(requests, s.ListPaymentsRequests)
|
||||
|
||||
return requests
|
||||
}
|
||||
|
||||
// NotifyHeight notifies a new block height.
|
||||
func (s *LndMockServices) NotifyHeight(height int32) error {
|
||||
s.lock.Lock()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue