Skip to content
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
9 changes: 9 additions & 0 deletions cmd/commands/walletrpc_active.go
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,14 @@ var bumpFeeCommand = cli.Command{
required. When the deadline is reached, ALL the budget will be spent as
fee.`,
},
cli.BoolFlag{
Name: "include_raw_tx",
Usage: `
Whether to include the raw transaction hex in the response. This is
useful for cases where the transaction does not propagate and the caller
wants to manually broadcast it. Note that setting this to true will
cause the command to block until the sweep transaction is created.`,
},
},
Action: actionDecorator(bumpFee),
}
Expand Down Expand Up @@ -359,6 +367,7 @@ func bumpFee(ctx *cli.Context) error {
Budget: ctx.Uint64("budget"),
SatPerVbyte: ctx.Uint64("sat_per_vbyte"),
DeadlineDelta: uint32(ctx.Uint64("deadline_delta")),
IncludeRawTx: ctx.Bool("include_raw_tx"),
})
if err != nil {
return err
Expand Down
6 changes: 5 additions & 1 deletion docs/release-notes/release-notes-0.20.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -293,9 +293,13 @@ reader of a payment request.
[removed](https://github.com/lightningnetwork/lnd/pull/9967) meaning that any
test network scripts that rely on bootstrapping being disabled will need to
explicitly define the `--nobootstrap` flag. Bootstrapping will now also be
[deterministic](https://github.com/lightningnetwork/lnd/pull/10003) on local
[deterministic](https://github.com/lightningnetwork/lnd/pull/10003) on local
test networks so that bootstrapping behaviour can be tested for.

* [Increased wallet sync timeout](https://github.com/lightningnetwork/lnd/pull/10323)
in integration tests from 30 seconds to 90 seconds to reduce test flakiness
in CI environments, particularly for the neutrino backend wallet sync tests.

## Database

* Add missing [sql index](https://github.com/lightningnetwork/lnd/pull/10155)
Expand Down
814 changes: 420 additions & 394 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 @@ -1241,11 +1241,25 @@ message BumpFeeRequest {
// fee function that the sweeper will use to bump the fee rate. When the
// deadline is reached, ALL the budget will be spent as fees.
uint32 deadline_delta = 8;

/*
Optional. Whether to include the raw transaction hex in the response. This
is useful for cases where the transaction does not propagate and the caller
wants to manually broadcast it.
*/
Comment on lines +1245 to +1249

Choose a reason for hiding this comment

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

medium

The comment for include_raw_tx should mention that setting this flag to true will cause the RPC call to block until the sweep transaction is created. This is a crucial detail for API users to understand the behavior of the call.

Suggested change
/*
Optional. Whether to include the raw transaction hex in the response. This
is useful for cases where the transaction does not propagate and the caller
wants to manually broadcast it.
*/
/*
Optional. Whether to include the raw transaction hex in the response. This
is useful for cases where the transaction does not propagate and the caller
wants to manually broadcast it. Note that setting this to true will cause
the RPC to block until the sweep transaction is created.
*/

bool include_raw_tx = 9;
}

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

/*
The raw transaction hex of the sweeping transaction. This field is only
populated if include_raw_tx was set to true in the request and the sweep
transaction was successfully created.
*/
string raw_tx = 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 @@ -1453,6 +1453,10 @@
"type": "integer",
"format": "int64",
"description": "Optional. The deadline delta in number of blocks that the output\nshould be spent within. This translates internally to the width of the\nfee function that the sweeper will use to bump the fee rate. When the\ndeadline is reached, ALL the budget will be spent as fees."
},
"include_raw_tx": {
"type": "boolean",
"description": "Optional. Whether to include the raw transaction hex in the response. This\nis useful for cases where the transaction does not propagate and the caller\nwants to manually broadcast it."
}
}
},
Expand All @@ -1462,6 +1466,10 @@
"status": {
"type": "string",
"description": "The status of the bump fee operation."
},
"raw_tx": {
"type": "string",
"description": "The raw transaction hex of the sweeping transaction. This field is only\npopulated if include_raw_tx was set to true in the request and the sweep\ntransaction was successfully created."
}
}
},
Expand Down
70 changes: 52 additions & 18 deletions lnrpc/walletrpc/walletkit_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"context"
"encoding/base64"
"encoding/binary"
"encoding/hex"
"errors"
"fmt"
"maps"
Expand Down Expand Up @@ -1151,27 +1152,59 @@ func (w *WalletKit) BumpFee(ctx context.Context,
return nil, err
}

var (
resultChan chan sweep.Result
status string
)

// If this input exists, we will update its params.
if existing {
_, err = w.cfg.Sweeper.UpdateParams(*op, params)
resultChan, err = w.cfg.Sweeper.UpdateParams(*op, params)
if err != nil {
return nil, err
}
status = "Successfully registered rbf-tx with sweeper"
} else {
// Otherwise, create a new sweeping request for this input.
resultChan, err = w.sweepNewInput(
op, uint32(currentHeight), params,
)
if err != nil {
return nil, err
}
status = "Successfully registered CPFP-tx with the sweeper"
}

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

// Otherwise, create a new sweeping request for this input.
err = w.sweepNewInput(op, uint32(currentHeight), params)
if err != nil {
return nil, err
// If the caller requested the raw transaction, wait for the sweep
// result and extract the transaction hex.
if in.IncludeRawTx {
select {
case result := <-resultChan:
if result.Err != nil {
return nil, fmt.Errorf("sweep failed: %w",
result.Err)
}

if result.Tx != nil {
var buf bytes.Buffer
err := result.Tx.Serialize(&buf)
if err != nil {
return nil, fmt.Errorf("failed to "+
"serialize tx: %w", err)
Comment on lines +1196 to +1197

Choose a reason for hiding this comment

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

medium

This string concatenation is unnecessary as the line is not exceeding the length limit. Combining it into a single string improves readability.1

return nil, fmt.Errorf("failed to serialize tx: %w", err)

Style Guide References

Footnotes

  1. The style guide recommends minimizing lines for log and error messages. While it allows splitting long strings, this string is short enough to be on a single line, which improves readability.

}
response.RawTx = hex.EncodeToString(buf.Bytes())
}

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

return &BumpFeeResponse{
Status: "Successfully registered CPFP-tx with the sweeper",
}, nil
return response, nil
}

// getWaitingCloseChannel returns the waiting close channel in case it does
Expand Down Expand Up @@ -1343,7 +1376,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 @@ -1356,12 +1389,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 @@ -1401,18 +1434,19 @@ 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
resultChan, err := w.cfg.Sweeper.SweepInput(inp, params)
if err != nil {
return nil, err
}

return nil
return resultChan, nil
}

// ListSweeps returns a list of the sweeps that our node has published.
Expand Down
4 changes: 2 additions & 2 deletions lnwallet/test/test_interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -3009,12 +3009,12 @@ func waitForWalletSync(r *rpctest.Harness, w *lnwallet.LightningWallet) error {
bestHash, knownHash *chainhash.Hash
bestHeight, knownHeight int32
)
timeout := time.After(30 * time.Second)
timeout := time.After(90 * time.Second)
for !synced {
// Do a short wait
select {
case <-timeout:
return errors.New("timeout after 30s")
return errors.New("timeout after 90s")
case <-time.Tick(100 * time.Millisecond):
}

Expand Down
Loading