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

lnrpc+cli: add optional raw tx hex resp to bumpfee cmd and rpc #8528

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
21 changes: 16 additions & 5 deletions cmd/commands/walletrpc_active.go
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,16 @@ var bumpFeeCommand = cli.Command{
the budget for fee bumping; for existing inputs, their current budgets
will be retained.`,
},
cli.BoolFlag{
Name: "include_raw_tx",
Usage: "include the raw transaction hex for the " +
"sweep transaction on success. " +
"It waits for the batcher to create a " +
"transaction, which might take a while. " +
"The duration is at least as long as " +
"the configured sweeper.batchwindowduration, " +
"with the default set to 30 seconds",
},
},
Action: actionDecorator(bumpFee),
}
Expand Down Expand Up @@ -344,11 +354,12 @@ func bumpFee(ctx *cli.Context) error {
}

resp, err := client.BumpFee(ctxc, &walletrpc.BumpFeeRequest{
Outpoint: protoOutPoint,
TargetConf: uint32(ctx.Uint64("conf_target")),
Immediate: immediate,
Budget: ctx.Uint64("budget"),
SatPerVbyte: ctx.Uint64("sat_per_vbyte"),
Outpoint: protoOutPoint,
TargetConf: uint32(ctx.Uint64("conf_target")),
Immediate: immediate,
Budget: ctx.Uint64("budget"),
SatPerVbyte: ctx.Uint64("sat_per_vbyte"),
IncludeRawTx: ctx.Bool("include_raw_tx"),
})
if err != nil {
return err
Expand Down
8 changes: 8 additions & 0 deletions docs/release-notes/release-notes-0.19.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,14 @@
range TLVs provided with the existing set of records on the HTLC,
overwriting any conflicting values with those supplied by the API.

* The `bumpfee` now optionally includes the raw transaction hex of the
sweep transaction in its command and RPC response. This allows users to
retrieve transaction details directly. Note that obtaining the raw transaction
hex may take some time based on the `sweeper.batchwindowduration`
configuration (default: 30 seconds). If the `immediate` flag is set to `true`
the raw transaction will be returned as soon as it is created. For more
details, see [PR #8528](https://github.com/lightningnetwork/lnd/pull/8528).

## lncli Updates

## Code Health
Expand Down
16 changes: 16 additions & 0 deletions lnrpc/rpc_utils.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package lnrpc

import (
"bytes"
"encoding/hex"
"errors"
"fmt"
"sort"

"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"github.com/lightningnetwork/lnd/lnwallet"
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
"github.com/lightningnetwork/lnd/sweep"
Expand Down Expand Up @@ -264,3 +266,17 @@ func CalculateFeeRate(satPerByte, satPerVByte uint64, targetConf uint32,

return feeRate, nil
}

// SerializeAndHexEncodeTx serializes the given wire transaction and returns
// its hexadecimal representation. If serialization fails, an error is
// returned.
func SerializeAndHexEncodeTx(tx *wire.MsgTx) (string, error) {
var txBuf bytes.Buffer
err := tx.Serialize(&txBuf)
if err != nil {
return "", fmt.Errorf("failed to serialize transaction: "+
"%w", err)
}

return hex.EncodeToString(txBuf.Bytes()), nil
}
803 changes: 416 additions & 387 deletions lnrpc/walletrpc/walletkit.pb.go

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions lnrpc/walletrpc/walletkit.proto
Original file line number Diff line number Diff line change
Expand Up @@ -1230,11 +1230,25 @@ message BumpFeeRequest {
retained.
*/
uint64 budget = 7;

/*
Indicates whether to include the raw transaction hex for the sweep
transaction. Note that this will wait for the batcher to create
a transaction, which might take a while. The duration is at least as long as
the configured sweeper.batchwindowduration value, with the default set to 30
seconds. In case `immediate` is set to true, the raw transaction will be
included as soon as the transaction is created.
*/
bool include_raw_tx = 8;
}

message BumpFeeResponse {
// The status of the bump fee operation.
string status = 1;

// The raw hex encoded bytes of the sweep transaction. Included if
// include_raw_tx in the request is true.
string sweep_tx_hex = 2;
}

message BumpForceCloseFeeRequest {
Expand Down
8 changes: 8 additions & 0 deletions lnrpc/walletrpc/walletkit.swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -1446,6 +1446,10 @@
"type": "string",
"format": "uint64",
"description": "Optional. The max amount in sats that can be used as the fees. Setting this\nvalue greater than the input's value may result in CPFP - one or more wallet\nutxos will be used to pay the fees specified by the budget. If not set, for\nnew inputs, by default 50% of the input's value will be treated as the\nbudget for fee bumping; for existing inputs, their current budgets will be\nretained."
},
"include_raw_tx": {
"type": "boolean",
"description": "Indicates whether to include the raw transaction hex for the sweep\ntransaction. Note that this will wait for the batcher to create\na transaction, which might take a while. The duration is at least as long as\nthe configured sweeper.batchwindowduration value, with the default set to 30\nseconds. In case `immediate` is set to true, the raw transaction will be\nincluded as soon as the transaction is created."
}
}
},
Expand All @@ -1455,6 +1459,10 @@
"status": {
"type": "string",
"description": "The status of the bump fee operation."
},
"sweep_tx_hex": {
"type": "string",
"description": "The raw hex encoded bytes of the sweep transaction. Included if\ninclude_raw_tx in the request is true."
}
}
},
Expand Down
59 changes: 48 additions & 11 deletions lnrpc/walletrpc/walletkit_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -1112,24 +1112,59 @@ func (w *WalletKit) BumpFee(ctx context.Context,

// If this input exists, we will update its params.
if existing {
_, err = w.cfg.Sweeper.UpdateParams(*op, params)
sweepChan, err := w.cfg.Sweeper.UpdateParams(*op, params)
if err != nil {
return nil, err
}

var sweepTxHex string
if in.IncludeRawTx {
select {
case sweepResult := <-sweepChan:
ellemouton marked this conversation as resolved.
Show resolved Hide resolved
sweepTxHex, err = lnrpc.SerializeAndHexEncodeTx(
sweepResult.Tx,
)
if err != nil {
return nil, err
}
case <-ctx.Done():
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: new line between cases 🙏

return nil, ctx.Err()
}
}

status := "Successfully registered rbf-tx with sweeper"
return &BumpFeeResponse{
Status: "Successfully registered rbf-tx with sweeper",
Status: status,
SweepTxHex: sweepTxHex,
}, nil
}

// Otherwise, create a new sweeping request for this input.
err = w.sweepNewInput(op, uint32(currentHeight), params)
sweepChan, err := w.sweepNewInput(op, uint32(currentHeight), params)
if err != nil {
return nil, err
}

var sweepTxHex string
if in.IncludeRawTx {
select {
case sweepResult := <-sweepChan:
sweepTxHex, err = lnrpc.SerializeAndHexEncodeTx(
sweepResult.Tx,
)
if err != nil {
return nil, err
}

case <-ctx.Done():
return nil, ctx.Err()
}
}

status := "Successfully registered CPFP-tx with the sweeper"
return &BumpFeeResponse{
Status: "Successfully registered CPFP-tx with the sweeper",
Status: status,
SweepTxHex: sweepTxHex,
}, nil
}

Expand Down Expand Up @@ -1301,7 +1336,7 @@ func (w *WalletKit) BumpForceCloseFee(_ context.Context,
//
// NOTE: if the budget is not set, the default budget ratio is used.
func (w *WalletKit) sweepNewInput(op *wire.OutPoint, currentHeight uint32,
params sweep.Params) error {
params sweep.Params) (chan sweep.Result, error) {

log.Debugf("Attempting to sweep outpoint %s", op)

Expand All @@ -1314,12 +1349,12 @@ func (w *WalletKit) sweepNewInput(op *wire.OutPoint, currentHeight uint32,
// order to sweep the output.
utxo, err := w.cfg.Wallet.FetchOutpointInfo(op)
if err != nil {
return err
return nil, err
}

// We're only able to bump the fee of unconfirmed transactions.
if utxo.Confirmations > 0 {
return errors.New("unable to bump fee of a confirmed " +
return nil, errors.New("unable to bump fee of a confirmed " +
"transaction")
}

Expand Down Expand Up @@ -1348,18 +1383,20 @@ func (w *WalletKit) sweepNewInput(op *wire.OutPoint, currentHeight uint32,
witnessType = input.TaprootPubKeySpend
signDesc.HashType = txscript.SigHashDefault
default:
return fmt.Errorf("unknown input witness %v", op)
return nil, fmt.Errorf("unknown input witness %v", op)
}

log.Infof("[BumpFee]: bumping fee for new input=%v, params=%v", op,
params)

inp := input.NewBaseInput(op, witnessType, signDesc, currentHeight)
if _, err = w.cfg.Sweeper.SweepInput(inp, params); err != nil {
return err

sweepChan, err := w.cfg.Sweeper.SweepInput(inp, params)
if err != nil {
return sweepChan, err
}

return nil
return sweepChan, nil
}

// ListSweeps returns a list of the sweeps that our node has published.
Expand Down
9 changes: 3 additions & 6 deletions rpcserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -4168,14 +4168,11 @@ func (r *rpcServer) fetchWaitingCloseChannels(
if closingTx != nil {
closingTxid = closingTx.TxHash().String()
if includeRawTx {
var txBuf bytes.Buffer
err = closingTx.Serialize(&txBuf)
closingTxHex, err =
lnrpc.SerializeAndHexEncodeTx(closingTx)
if err != nil {
return nil, 0, fmt.Errorf("failed to "+
"serialize closing transaction"+
": %w", err)
return nil, 0, err
}
closingTxHex = hex.EncodeToString(txBuf.Bytes())
}
}

Expand Down
Loading