mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-05-15 06:10:07 +02:00
Merge pull request #8426 from breez/expose-closing-tx
Expose closing tx in waiting_close_channels
This commit is contained in:
commit
dd7b186622
@ -1445,7 +1445,14 @@ var pendingChannelsCommand = cli.Command{
|
|||||||
Name: "pendingchannels",
|
Name: "pendingchannels",
|
||||||
Category: "Channels",
|
Category: "Channels",
|
||||||
Usage: "Display information pertaining to pending channels.",
|
Usage: "Display information pertaining to pending channels.",
|
||||||
Action: actionDecorator(pendingChannels),
|
Flags: []cli.Flag{
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "include_raw_tx",
|
||||||
|
Usage: "include the raw transaction hex for " +
|
||||||
|
"waiting_close_channels.",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: actionDecorator(pendingChannels),
|
||||||
}
|
}
|
||||||
|
|
||||||
func pendingChannels(ctx *cli.Context) error {
|
func pendingChannels(ctx *cli.Context) error {
|
||||||
@ -1453,7 +1460,10 @@ func pendingChannels(ctx *cli.Context) error {
|
|||||||
client, cleanUp := getClient(ctx)
|
client, cleanUp := getClient(ctx)
|
||||||
defer cleanUp()
|
defer cleanUp()
|
||||||
|
|
||||||
req := &lnrpc.PendingChannelsRequest{}
|
includeRawTx := ctx.Bool("include_raw_tx")
|
||||||
|
req := &lnrpc.PendingChannelsRequest{
|
||||||
|
IncludeRawTx: includeRawTx,
|
||||||
|
}
|
||||||
resp, err := client.PendingChannels(ctxc, req)
|
resp, err := client.PendingChannels(ctxc, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -187,6 +187,10 @@
|
|||||||
[MinConf](https://github.com/lightningnetwork/lnd/pull/8097)(minimum number
|
[MinConf](https://github.com/lightningnetwork/lnd/pull/8097)(minimum number
|
||||||
of confirmations) has been added to the `WalletBalance` RPC call.
|
of confirmations) has been added to the `WalletBalance` RPC call.
|
||||||
|
|
||||||
|
* `PendingChannels` now optionally returns the
|
||||||
|
[raw hex of the closing tx](https://github.com/lightningnetwork/lnd/pull/8426)
|
||||||
|
in `waiting_close_channels`.
|
||||||
|
|
||||||
## lncli Updates
|
## lncli Updates
|
||||||
|
|
||||||
* [Documented all available lncli commands](https://github.com/lightningnetwork/lnd/pull/8181).
|
* [Documented all available lncli commands](https://github.com/lightningnetwork/lnd/pull/8181).
|
||||||
@ -202,6 +206,10 @@
|
|||||||
* [Use the default LND value in the buildroute rpc command for the
|
* [Use the default LND value in the buildroute rpc command for the
|
||||||
final cltv delta](https://github.com/lightningnetwork/lnd/pull/8387).
|
final cltv delta](https://github.com/lightningnetwork/lnd/pull/8387).
|
||||||
|
|
||||||
|
* `pendingchannels` now optionally returns the
|
||||||
|
[raw hex of the closing tx](https://github.com/lightningnetwork/lnd/pull/8426)
|
||||||
|
in `waiting_close_channels`.
|
||||||
|
|
||||||
## Code Health
|
## Code Health
|
||||||
|
|
||||||
* [Remove Litecoin code](https://github.com/lightningnetwork/lnd/pull/7867).
|
* [Remove Litecoin code](https://github.com/lightningnetwork/lnd/pull/7867).
|
||||||
@ -287,6 +295,7 @@
|
|||||||
* Carla Kirk-Cohen
|
* Carla Kirk-Cohen
|
||||||
* Elle Mouton
|
* Elle Mouton
|
||||||
* ErikEk
|
* ErikEk
|
||||||
|
* Jesse de Wit
|
||||||
* Keagan McClelland
|
* Keagan McClelland
|
||||||
* Marcos Fernandez Perez
|
* Marcos Fernandez Perez
|
||||||
* Matt Morehouse
|
* Matt Morehouse
|
||||||
|
@ -2,6 +2,7 @@ package itest
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@ -141,7 +142,24 @@ func testCommitmentTransactionDeadline(ht *lntest.HarnessTest) {
|
|||||||
// Now that the channel has been force closed, it should show
|
// Now that the channel has been force closed, it should show
|
||||||
// up in the PendingChannels RPC under the waiting close
|
// up in the PendingChannels RPC under the waiting close
|
||||||
// section.
|
// section.
|
||||||
ht.AssertChannelWaitingClose(alice, chanPoint)
|
waitingClose := ht.AssertChannelWaitingClose(alice, chanPoint)
|
||||||
|
|
||||||
|
// The waiting close channel closing tx hex should be set and
|
||||||
|
// be valid.
|
||||||
|
require.NotEmpty(ht, waitingClose.ClosingTxHex)
|
||||||
|
rawTxBytes, err := hex.DecodeString(waitingClose.ClosingTxHex)
|
||||||
|
require.NoError(
|
||||||
|
ht, err,
|
||||||
|
"waiting close channel closingTxHex invalid hex",
|
||||||
|
)
|
||||||
|
rawTx := &wire.MsgTx{}
|
||||||
|
err = rawTx.Deserialize(bytes.NewReader(rawTxBytes))
|
||||||
|
require.NoError(
|
||||||
|
ht, err, "waiting close channel ClosingTxHex invalid",
|
||||||
|
)
|
||||||
|
require.Equal(
|
||||||
|
ht, waitingClose.ClosingTxid, rawTx.TxHash().String(),
|
||||||
|
)
|
||||||
|
|
||||||
// We should see Alice's force closing tx in the mempool.
|
// We should see Alice's force closing tx in the mempool.
|
||||||
expectedNumTxes := 1
|
expectedNumTxes := 1
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -586,10 +586,21 @@ func local_request_Lightning_GetRecoveryInfo_0(ctx context.Context, marshaler ru
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
filter_Lightning_PendingChannels_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
|
||||||
|
)
|
||||||
|
|
||||||
func request_Lightning_PendingChannels_0(ctx context.Context, marshaler runtime.Marshaler, client LightningClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
func request_Lightning_PendingChannels_0(ctx context.Context, marshaler runtime.Marshaler, client LightningClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
var protoReq PendingChannelsRequest
|
var protoReq PendingChannelsRequest
|
||||||
var metadata runtime.ServerMetadata
|
var metadata runtime.ServerMetadata
|
||||||
|
|
||||||
|
if err := req.ParseForm(); err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
|
}
|
||||||
|
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Lightning_PendingChannels_0); err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
msg, err := client.PendingChannels(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
msg, err := client.PendingChannels(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||||
return msg, metadata, err
|
return msg, metadata, err
|
||||||
|
|
||||||
@ -599,6 +610,13 @@ func local_request_Lightning_PendingChannels_0(ctx context.Context, marshaler ru
|
|||||||
var protoReq PendingChannelsRequest
|
var protoReq PendingChannelsRequest
|
||||||
var metadata runtime.ServerMetadata
|
var metadata runtime.ServerMetadata
|
||||||
|
|
||||||
|
if err := req.ParseForm(); err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
|
}
|
||||||
|
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Lightning_PendingChannels_0); err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
msg, err := server.PendingChannels(ctx, &protoReq)
|
msg, err := server.PendingChannels(ctx, &protoReq)
|
||||||
return msg, metadata, err
|
return msg, metadata, err
|
||||||
|
|
||||||
|
@ -2636,6 +2636,9 @@ message PendingHTLC {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message PendingChannelsRequest {
|
message PendingChannelsRequest {
|
||||||
|
// Indicates whether to include the raw transaction hex for
|
||||||
|
// waiting_close_channels.
|
||||||
|
bool include_raw_tx = 1;
|
||||||
}
|
}
|
||||||
message PendingChannelsResponse {
|
message PendingChannelsResponse {
|
||||||
message PendingChannel {
|
message PendingChannel {
|
||||||
@ -2733,6 +2736,10 @@ message PendingChannelsResponse {
|
|||||||
|
|
||||||
// The transaction id of the closing transaction
|
// The transaction id of the closing transaction
|
||||||
string closing_txid = 4;
|
string closing_txid = 4;
|
||||||
|
|
||||||
|
// The raw hex encoded bytes of the closing transaction. Included if
|
||||||
|
// include_raw_tx in the request is true.
|
||||||
|
string closing_tx_hex = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
message Commitments {
|
message Commitments {
|
||||||
|
@ -582,6 +582,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "include_raw_tx",
|
||||||
|
"description": "Indicates whether to include the raw transaction hex for\nwaiting_close_channels.",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"Lightning"
|
"Lightning"
|
||||||
]
|
]
|
||||||
@ -3140,6 +3149,10 @@
|
|||||||
"closing_txid": {
|
"closing_txid": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"title": "The transaction id of the closing transaction"
|
"title": "The transaction id of the closing transaction"
|
||||||
|
},
|
||||||
|
"closing_tx_hex": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The raw hex encoded bytes of the closing transaction. Included if\ninclude_raw_tx in the request is true."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -131,7 +131,9 @@ func (h *HarnessRPC) PendingChannels() *lnrpc.PendingChannelsResponse {
|
|||||||
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
|
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
pendingChansRequest := &lnrpc.PendingChannelsRequest{}
|
pendingChansRequest := &lnrpc.PendingChannelsRequest{
|
||||||
|
IncludeRawTx: true,
|
||||||
|
}
|
||||||
resp, err := h.LN.PendingChannels(ctxt, pendingChansRequest)
|
resp, err := h.LN.PendingChannels(ctxt, pendingChansRequest)
|
||||||
|
|
||||||
// TODO(yy): We may get a `unable to find arbitrator` error from the
|
// TODO(yy): We may get a `unable to find arbitrator` error from the
|
||||||
|
63
rpcserver.go
63
rpcserver.go
@ -3718,8 +3718,8 @@ func (r *rpcServer) fetchPendingForceCloseChannels() (pendingForceClose,
|
|||||||
// fetchWaitingCloseChannels queries the database for a list of channels
|
// fetchWaitingCloseChannels queries the database for a list of channels
|
||||||
// that have their closing transactions broadcast but not confirmed yet.
|
// that have their closing transactions broadcast but not confirmed yet.
|
||||||
// The returned result is used in the response of the PendingChannels RPC.
|
// The returned result is used in the response of the PendingChannels RPC.
|
||||||
func (r *rpcServer) fetchWaitingCloseChannels() (waitingCloseChannels,
|
func (r *rpcServer) fetchWaitingCloseChannels(
|
||||||
int64, error) {
|
includeRawTx bool) (waitingCloseChannels, int64, error) {
|
||||||
|
|
||||||
// We'll also fetch all channels that are open, but have had their
|
// We'll also fetch all channels that are open, but have had their
|
||||||
// commitment broadcasted, meaning they are waiting for the closing
|
// commitment broadcasted, meaning they are waiting for the closing
|
||||||
@ -3734,43 +3734,42 @@ func (r *rpcServer) fetchWaitingCloseChannels() (waitingCloseChannels,
|
|||||||
result := make(waitingCloseChannels, 0)
|
result := make(waitingCloseChannels, 0)
|
||||||
limboBalance := int64(0)
|
limboBalance := int64(0)
|
||||||
|
|
||||||
// getClosingTx is a helper closure that tries to find the closing txid
|
// getClosingTx is a helper closure that tries to find the closing tx of
|
||||||
// of a given waiting close channel. Notice that if the remote closes
|
// a given waiting close channel. Notice that if the remote closes the
|
||||||
// the channel, we may not have the closing txid.
|
// channel, we may not have the closing tx.
|
||||||
getClosingTx := func(c *channeldb.OpenChannel) (string, error) {
|
getClosingTx := func(c *channeldb.OpenChannel) (*wire.MsgTx, error) {
|
||||||
var (
|
var (
|
||||||
tx *wire.MsgTx
|
tx *wire.MsgTx
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
// First, we try to locate the force closing txid. If not
|
// First, we try to locate the force closing tx. If not found,
|
||||||
// found, we will then try to find its coop closing txid.
|
// we will then try to find its coop closing tx.
|
||||||
tx, err = c.BroadcastedCommitment()
|
tx, err = c.BroadcastedCommitment()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return tx.TxHash().String(), nil
|
return tx, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the error returned is not ErrNoCloseTx, something
|
// If the error returned is not ErrNoCloseTx, something
|
||||||
// unexpected happened and we will return the error.
|
// unexpected happened and we will return the error.
|
||||||
if err != channeldb.ErrNoCloseTx {
|
if err != channeldb.ErrNoCloseTx {
|
||||||
return "", err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, we continue to locate its coop closing txid.
|
// Otherwise, we continue to locate its coop closing tx.
|
||||||
tx, err = c.BroadcastedCooperative()
|
tx, err = c.BroadcastedCooperative()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return tx.TxHash().String(), nil
|
return tx, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the error if it's not ErrNoCloseTx.
|
// Return the error if it's not ErrNoCloseTx.
|
||||||
if err != channeldb.ErrNoCloseTx {
|
if err != channeldb.ErrNoCloseTx {
|
||||||
return "", err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise return an empty txid. This can happen if the
|
// Otherwise return an empty tx. This can happen if the remote
|
||||||
// remote broadcast the closing txid and we haven't recorded it
|
// broadcast the closing tx and we haven't recorded it yet.
|
||||||
// yet.
|
return nil, nil
|
||||||
return "", nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, waitingClose := range channels {
|
for _, waitingClose := range channels {
|
||||||
@ -3830,12 +3829,12 @@ func (r *rpcServer) fetchWaitingCloseChannels() (waitingCloseChannels,
|
|||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the closing txid.
|
// Get the closing tx.
|
||||||
// NOTE: the closing txid could be empty here if it's the
|
// NOTE: the closing tx could be nil here if it's the remote
|
||||||
// remote broadcasted the closing tx.
|
// that broadcasted the closing tx.
|
||||||
closingTxid, err := getClosingTx(waitingClose)
|
closingTx, err := getClosingTx(waitingClose)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rpcsLog.Errorf("unable to find closing txid for "+
|
rpcsLog.Errorf("unable to find closing tx for "+
|
||||||
"channel:%s, %v",
|
"channel:%s, %v",
|
||||||
waitingClose.ShortChannelID, err)
|
waitingClose.ShortChannelID, err)
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
@ -3857,11 +3856,27 @@ func (r *rpcServer) fetchWaitingCloseChannels() (waitingCloseChannels,
|
|||||||
Memo: string(waitingClose.Memo),
|
Memo: string(waitingClose.Memo),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var closingTxid, closingTxHex string
|
||||||
|
if closingTx != nil {
|
||||||
|
closingTxid = closingTx.TxHash().String()
|
||||||
|
if includeRawTx {
|
||||||
|
var txBuf bytes.Buffer
|
||||||
|
err = closingTx.Serialize(&txBuf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, fmt.Errorf("failed to "+
|
||||||
|
"serialize closing transaction"+
|
||||||
|
": %w", err)
|
||||||
|
}
|
||||||
|
closingTxHex = hex.EncodeToString(txBuf.Bytes())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
waitingCloseResp := &lnrpc.PendingChannelsResponse_WaitingCloseChannel{
|
waitingCloseResp := &lnrpc.PendingChannelsResponse_WaitingCloseChannel{
|
||||||
Channel: channel,
|
Channel: channel,
|
||||||
LimboBalance: channel.LocalBalance,
|
LimboBalance: channel.LocalBalance,
|
||||||
Commitments: &commitments,
|
Commitments: &commitments,
|
||||||
ClosingTxid: closingTxid,
|
ClosingTxid: closingTxid,
|
||||||
|
ClosingTxHex: closingTxHex,
|
||||||
}
|
}
|
||||||
|
|
||||||
// A close tx has been broadcasted, all our balance will be in
|
// A close tx has been broadcasted, all our balance will be in
|
||||||
@ -3904,7 +3919,9 @@ func (r *rpcServer) PendingChannels(ctx context.Context,
|
|||||||
// Third, we fetch all channels that are open, but have had their
|
// Third, we fetch all channels that are open, but have had their
|
||||||
// commitment broadcasted, meaning they are waiting for the closing
|
// commitment broadcasted, meaning they are waiting for the closing
|
||||||
// transaction to confirm.
|
// transaction to confirm.
|
||||||
waitingCloseChannels, limbo, err := r.fetchWaitingCloseChannels()
|
waitingCloseChannels, limbo, err := r.fetchWaitingCloseChannels(
|
||||||
|
in.IncludeRawTx,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user