Merge pull request #8426 from breez/expose-closing-tx

Expose closing tx in waiting_close_channels
This commit is contained in:
Yong 2024-01-30 09:13:17 +08:00 committed by GitHub
commit dd7b186622
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 2020 additions and 1900 deletions

View File

@ -1445,7 +1445,14 @@ var pendingChannelsCommand = cli.Command{
Name: "pendingchannels",
Category: "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 {
@ -1453,7 +1460,10 @@ func pendingChannels(ctx *cli.Context) error {
client, cleanUp := getClient(ctx)
defer cleanUp()
req := &lnrpc.PendingChannelsRequest{}
includeRawTx := ctx.Bool("include_raw_tx")
req := &lnrpc.PendingChannelsRequest{
IncludeRawTx: includeRawTx,
}
resp, err := client.PendingChannels(ctxc, req)
if err != nil {
return err

View File

@ -187,6 +187,10 @@
[MinConf](https://github.com/lightningnetwork/lnd/pull/8097)(minimum number
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
* [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
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
* [Remove Litecoin code](https://github.com/lightningnetwork/lnd/pull/7867).
@ -287,6 +295,7 @@
* Carla Kirk-Cohen
* Elle Mouton
* ErikEk
* Jesse de Wit
* Keagan McClelland
* Marcos Fernandez Perez
* Matt Morehouse

View File

@ -2,6 +2,7 @@ package itest
import (
"bytes"
"encoding/hex"
"fmt"
"testing"
@ -141,7 +142,24 @@ func testCommitmentTransactionDeadline(ht *lntest.HarnessTest) {
// Now that the channel has been force closed, it should show
// up in the PendingChannels RPC under the waiting close
// 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.
expectedNumTxes := 1

File diff suppressed because it is too large Load Diff

View File

@ -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) {
var protoReq PendingChannelsRequest
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))
return msg, metadata, err
@ -599,6 +610,13 @@ func local_request_Lightning_PendingChannels_0(ctx context.Context, marshaler ru
var protoReq PendingChannelsRequest
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)
return msg, metadata, err

View File

@ -2636,6 +2636,9 @@ message PendingHTLC {
}
message PendingChannelsRequest {
// Indicates whether to include the raw transaction hex for
// waiting_close_channels.
bool include_raw_tx = 1;
}
message PendingChannelsResponse {
message PendingChannel {
@ -2733,6 +2736,10 @@ message PendingChannelsResponse {
// The transaction id of the closing transaction
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 {

View File

@ -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": [
"Lightning"
]
@ -3140,6 +3149,10 @@
"closing_txid": {
"type": "string",
"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."
}
}
},

View File

@ -131,7 +131,9 @@ func (h *HarnessRPC) PendingChannels() *lnrpc.PendingChannelsResponse {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
pendingChansRequest := &lnrpc.PendingChannelsRequest{}
pendingChansRequest := &lnrpc.PendingChannelsRequest{
IncludeRawTx: true,
}
resp, err := h.LN.PendingChannels(ctxt, pendingChansRequest)
// TODO(yy): We may get a `unable to find arbitrator` error from the

View File

@ -3718,8 +3718,8 @@ func (r *rpcServer) fetchPendingForceCloseChannels() (pendingForceClose,
// fetchWaitingCloseChannels queries the database for a list of channels
// that have their closing transactions broadcast but not confirmed yet.
// The returned result is used in the response of the PendingChannels RPC.
func (r *rpcServer) fetchWaitingCloseChannels() (waitingCloseChannels,
int64, error) {
func (r *rpcServer) fetchWaitingCloseChannels(
includeRawTx bool) (waitingCloseChannels, int64, error) {
// We'll also fetch all channels that are open, but have had their
// commitment broadcasted, meaning they are waiting for the closing
@ -3734,43 +3734,42 @@ func (r *rpcServer) fetchWaitingCloseChannels() (waitingCloseChannels,
result := make(waitingCloseChannels, 0)
limboBalance := int64(0)
// getClosingTx is a helper closure that tries to find the closing txid
// of a given waiting close channel. Notice that if the remote closes
// the channel, we may not have the closing txid.
getClosingTx := func(c *channeldb.OpenChannel) (string, error) {
// getClosingTx is a helper closure that tries to find the closing tx of
// a given waiting close channel. Notice that if the remote closes the
// channel, we may not have the closing tx.
getClosingTx := func(c *channeldb.OpenChannel) (*wire.MsgTx, error) {
var (
tx *wire.MsgTx
err error
)
// First, we try to locate the force closing txid. If not
// found, we will then try to find its coop closing txid.
// First, we try to locate the force closing tx. If not found,
// we will then try to find its coop closing tx.
tx, err = c.BroadcastedCommitment()
if err == nil {
return tx.TxHash().String(), nil
return tx, nil
}
// If the error returned is not ErrNoCloseTx, something
// unexpected happened and we will return the error.
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()
if err == nil {
return tx.TxHash().String(), nil
return tx, nil
}
// Return the error if it's not ErrNoCloseTx.
if err != channeldb.ErrNoCloseTx {
return "", err
return nil, err
}
// Otherwise return an empty txid. This can happen if the
// remote broadcast the closing txid and we haven't recorded it
// yet.
return "", nil
// Otherwise return an empty tx. This can happen if the remote
// broadcast the closing tx and we haven't recorded it yet.
return nil, nil
}
for _, waitingClose := range channels {
@ -3830,12 +3829,12 @@ func (r *rpcServer) fetchWaitingCloseChannels() (waitingCloseChannels,
return nil, 0, err
}
// Get the closing txid.
// NOTE: the closing txid could be empty here if it's the
// remote broadcasted the closing tx.
closingTxid, err := getClosingTx(waitingClose)
// Get the closing tx.
// NOTE: the closing tx could be nil here if it's the remote
// that broadcasted the closing tx.
closingTx, err := getClosingTx(waitingClose)
if err != nil {
rpcsLog.Errorf("unable to find closing txid for "+
rpcsLog.Errorf("unable to find closing tx for "+
"channel:%s, %v",
waitingClose.ShortChannelID, err)
return nil, 0, err
@ -3857,11 +3856,27 @@ func (r *rpcServer) fetchWaitingCloseChannels() (waitingCloseChannels,
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{
Channel: channel,
LimboBalance: channel.LocalBalance,
Commitments: &commitments,
ClosingTxid: closingTxid,
ClosingTxHex: closingTxHex,
}
// 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
// commitment broadcasted, meaning they are waiting for the closing
// transaction to confirm.
waitingCloseChannels, limbo, err := r.fetchWaitingCloseChannels()
waitingCloseChannels, limbo, err := r.fetchWaitingCloseChannels(
in.IncludeRawTx,
)
if err != nil {
return nil, err
}