Skip to content

High-level API for feebumping channel funding #4971

@ZmnSCPxj

Description

@ZmnSCPxj

While we now have a openchannel_bump command that lets channel opening attempts to be feebumped, the API is low-level and requires a fair amount of handling at the caller.

Let me propose some changes to fundchannel/multifundchannel, as well as new APIs listfundchannels, bumpfundchannel, and isbumpablemultifundchannel.

multifundchannel/fundchannel

fundchannel is just a thin wrapper around multifundchannel, so I will describe multifundchannel.

We add two new outputs, fundchannel_uuid and bumpable. fundchannel_uuid is simply a large random hex string that uniquely identifies this multifundchannel attempt. bumpable is true if all nodes support feebumping (i.e. all nodes in the multifundchannel support openv2), false otherwise.

What happens is that we use the datastore API. We add a key lightning/plugins/spenderp/listfundchannels as a parent key, with the UUIDs as child keys. Before multifundchannel returns, generate a UUID and store the data on the db:

  • The outputs that were reserved and spent by the transaction ID.
  • The node IDs we created channels to, and the outputs / channel IDs they got.
  • The exact feerate used.
  • The weight of the funding tx.
  • Whether it is bumpable or not.
  • A lock; this is either empty (the initial value), or the process ID of the spenderp plugin that locked this entry.

listfundchannels

listfundchannels [fundchannel_uuid_or_node_id]

Given no arguments this simply does listdatastore on the lightning/plugins/spenderp/listfundchannels key, and parses the returned data and prints it out in JSON, including the fundchannel_uuid.

Given an argument, it identifies it as either a UUID or a node ID. If a UUID it just parses the specific UUID and returns the data. If a node ID it looks through listdatastore and looks for the entry where the given node ID is listed.

We also run a background task. We waitblockheight starting at 0, then we listfundchannels with no arguments. If at least one node in a particular fundchannel_uuid has entered CHANNELD_NORMAL state, then we delete it. Then we just loop again, taking the blockheight returned by the previous waitblockheight + 1.

bumpfundchannel

bumpfundchannel fundchannel_uuid_or_node_id [deltafeerate]

This attempts to bump the given multifundchannel attempt. If deltafeerate is specified it is the feerate to add to the previous feerate, and must be at least 253perkw. If unspecified it defaults to 253perkw.

From what I understand of the RBFing flow, it would look like this:

  • First listfundchannels the fundchannel_uuid_or_node_id argument to get the fundchannel_uuid we should be using.
    • If non-existent, return a "fundchannel_uuid not found" error.
  • Lock the fundchannel_uuid.
    • If the lock is nonexistent, or contains a different process ID, then consider it as unlocked and atomically lock it by writing our process ID into the lock field.
      • TODO: deterministic startup probably means on a computer reboot we might get the same process ID anyway, how do we fix this?
  • Update the feerate.
  • Attempt a utxopsbt with the current inputs and the new feerate.
    • This can fail with error code 301. If so, find a new output:
      • Do a fundpsbt with the dust limit as target satoshi, and a startweight of zero, and with feerate equal to the current feerate.
      • If that succeeds to find an input, add the input to the fundchannel_uuid db entry and increase the weight by that input, and reattempt the utxopsbt.
  • Unlock the feechannel_uuid.
  • Do openchannel_bump on each of the nodes.
    • @niftynei does it need to be in sequence or can this be done in parallel? How do the channel outputs get populated?
  • Do openchannel_update on each of the nodes.
  • Sign the resulting final PSBT.
  • Do openchannel_signed on each of the nodes.
  • ? more?

isbumpablemultifundchannel

isbumpablemultifundchannel node_ids

node_ids is an array of node IDs. This checks if all the given nodes have the openv2 feature bit set. If so, it returns a bumpable of true, otherwise it returns a bumpable of false. Convenience API so that automated node managers can know beforehand if it can lowball first and feebump later, given a particular set of candidate nodes, or if it has to highball now because it cannot feebump later because nobody upgrades their software.

Metadata

Metadata

Assignees

Labels

featureAimed at improving the existing functionality or a new feature that provides additional value

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions