126f79dbb1
We add a new funding assembler and intent type that handle channel funding through the use of a PSBT. The PsbtIntent is in itself a simple state machine that can be stepped through the process of assembling the required information for the funding output, verifying a user supplied PSBT for correctness, accepting a fully signed PSBT and then assembling the funding wire message.
138 lines
5.4 KiB
Go
138 lines
5.4 KiB
Go
package chanfunding
|
|
|
|
import (
|
|
"github.com/btcsuite/btcd/wire"
|
|
"github.com/btcsuite/btcutil"
|
|
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
|
)
|
|
|
|
// CoinSource is an interface that allows a caller to access a source of UTXOs
|
|
// to use when attempting to fund a new channel.
|
|
type CoinSource interface {
|
|
// ListCoins returns all UTXOs from the source that have between
|
|
// minConfs and maxConfs number of confirmations.
|
|
ListCoins(minConfs, maxConfs int32) ([]Coin, error)
|
|
|
|
// CoinFromOutPoint attempts to locate details pertaining to a coin
|
|
// based on its outpoint. If the coin isn't under the control of the
|
|
// backing CoinSource, then an error should be returned.
|
|
CoinFromOutPoint(wire.OutPoint) (*Coin, error)
|
|
}
|
|
|
|
// CoinSelectionLocker is an interface that allows the caller to perform an
|
|
// operation, which is synchronized with all coin selection attempts. This can
|
|
// be used when an operation requires that all coin selection operations cease
|
|
// forward progress. Think of this as an exclusive lock on coin selection
|
|
// operations.
|
|
type CoinSelectionLocker interface {
|
|
// WithCoinSelectLock will execute the passed function closure in a
|
|
// synchronized manner preventing any coin selection operations from
|
|
// proceeding while the closure is executing. This can be seen as the
|
|
// ability to execute a function closure under an exclusive coin
|
|
// selection lock.
|
|
WithCoinSelectLock(func() error) error
|
|
}
|
|
|
|
// OutpointLocker allows a caller to lock/unlock an outpoint. When locked, the
|
|
// outpoints shouldn't be used for any sort of channel funding of coin
|
|
// selection. Locked outpoints are not expected to be persisted between
|
|
// restarts.
|
|
type OutpointLocker interface {
|
|
// LockOutpoint locks a target outpoint, rendering it unusable for coin
|
|
// selection.
|
|
LockOutpoint(o wire.OutPoint)
|
|
|
|
// UnlockOutpoint unlocks a target outpoint, allowing it to be used for
|
|
// coin selection once again.
|
|
UnlockOutpoint(o wire.OutPoint)
|
|
}
|
|
|
|
// Request is a new request for funding a channel. The items in the struct
|
|
// governs how the final channel point will be provisioned by the target
|
|
// Assembler.
|
|
type Request struct {
|
|
// LocalAmt is the amount of coins we're placing into the funding
|
|
// output.
|
|
LocalAmt btcutil.Amount
|
|
|
|
// RemoteAmt is the amount of coins the remote party is contributing to
|
|
// the funding output.
|
|
RemoteAmt btcutil.Amount
|
|
|
|
// MinConfs controls how many confirmations a coin need to be eligible
|
|
// to be used as an input to the funding transaction. If this value is
|
|
// set to zero, then zero conf outputs may be spent.
|
|
MinConfs int32
|
|
|
|
// SubtractFees should be set if we intend to spend exactly LocalAmt
|
|
// when opening the channel, subtracting the fees from the funding
|
|
// output. This can be used for instance to use all our remaining funds
|
|
// to open the channel, since it will take fees into
|
|
// account.
|
|
SubtractFees bool
|
|
|
|
// FeeRate is the fee rate in sat/kw that the funding transaction
|
|
// should carry.
|
|
FeeRate chainfee.SatPerKWeight
|
|
|
|
// ChangeAddr is a closure that will provide the Assembler with a
|
|
// change address for the funding transaction if needed.
|
|
ChangeAddr func() (btcutil.Address, error)
|
|
}
|
|
|
|
// Intent is returned by an Assembler and represents the base functionality the
|
|
// caller needs to proceed with channel funding on a higher level. If the
|
|
// Cancel method is called, then all resources assembled to fund the channel
|
|
// will be released back to the eligible pool.
|
|
type Intent interface {
|
|
// FundingOutput returns the witness script, and the output that
|
|
// creates the funding output.
|
|
FundingOutput() ([]byte, *wire.TxOut, error)
|
|
|
|
// ChanPoint returns the final outpoint that will create the funding
|
|
// output described above.
|
|
ChanPoint() (*wire.OutPoint, error)
|
|
|
|
// RemoteFundingAmt is the amount the remote party put into the
|
|
// channel.
|
|
RemoteFundingAmt() btcutil.Amount
|
|
|
|
// LocalFundingAmt is the amount we put into the channel. This may
|
|
// differ from the local amount requested, as depending on coin
|
|
// selection, we may bleed from of that LocalAmt into fees to minimize
|
|
// change.
|
|
LocalFundingAmt() btcutil.Amount
|
|
|
|
// Cancel allows the caller to cancel a funding Intent at any time.
|
|
// This will return any resources such as coins back to the eligible
|
|
// pool to be used in order channel fundings.
|
|
Cancel()
|
|
}
|
|
|
|
// Assembler is an abstract object that is capable of assembling everything
|
|
// needed to create a new funding output. As an example, this assembler may be
|
|
// our core backing wallet, an interactive PSBT based assembler, an assembler
|
|
// than can aggregate multiple intents into a single funding transaction, or an
|
|
// external protocol that creates a funding output out-of-band such as channel
|
|
// factories.
|
|
type Assembler interface {
|
|
// ProvisionChannel returns a populated Intent that can be used to
|
|
// further the channel funding workflow. Depending on the
|
|
// implementation of Assembler, additional state machine (Intent)
|
|
// actions may be required before the FundingOutput and ChanPoint are
|
|
// made available to the caller.
|
|
ProvisionChannel(*Request) (Intent, error)
|
|
}
|
|
|
|
// FundingTxAssembler is a super-set of the regular Assembler interface that's
|
|
// also able to provide a fully populated funding transaction via the intents
|
|
// that it produces.
|
|
type FundingTxAssembler interface {
|
|
Assembler
|
|
|
|
// FundingTxAvailable is an empty method that an assembler can
|
|
// implement to signal to callers that its able to provide the funding
|
|
// transaction for the channel via the intent it returns.
|
|
FundingTxAvailable()
|
|
}
|