mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-08-30 23:53:41 +02:00
lnwallet: add new RegisterFundingIntent method
In this commit, we add a new method `RegisterFundingIntent` that allows a caller to "inject" a pre-populated chanfunding.Intent into a funding workflow. As an example, if we've already agreed upon the "shape" of the funding output _outside_ the protocol, then we can use this to pass down the details of the output, then leverage the normal wire protocol to carry out the remainder of the funding flow.
This commit is contained in:
@@ -277,6 +277,11 @@ type LightningWallet struct {
|
|||||||
// the currently locked outpoints.
|
// the currently locked outpoints.
|
||||||
lockedOutPoints map[wire.OutPoint]struct{}
|
lockedOutPoints map[wire.OutPoint]struct{}
|
||||||
|
|
||||||
|
// fundingIntents houses all the "interception" registered by a caller
|
||||||
|
// using the RegisterFundingIntent method.
|
||||||
|
intentMtx sync.RWMutex
|
||||||
|
fundingIntents map[[32]byte]chanfunding.Intent
|
||||||
|
|
||||||
quit chan struct{}
|
quit chan struct{}
|
||||||
|
|
||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
@@ -297,6 +302,7 @@ func NewLightningWallet(Cfg Config) (*LightningWallet, error) {
|
|||||||
nextFundingID: 0,
|
nextFundingID: 0,
|
||||||
fundingLimbo: make(map[uint64]*ChannelReservation),
|
fundingLimbo: make(map[uint64]*ChannelReservation),
|
||||||
lockedOutPoints: make(map[wire.OutPoint]struct{}),
|
lockedOutPoints: make(map[wire.OutPoint]struct{}),
|
||||||
|
fundingIntents: make(map[[32]byte]chanfunding.Intent),
|
||||||
quit: make(chan struct{}),
|
quit: make(chan struct{}),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
@@ -435,6 +441,21 @@ func (l *LightningWallet) InitChannelReservation(
|
|||||||
return <-req.resp, <-req.err
|
return <-req.resp, <-req.err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RegisterFundingIntent allows a caller to signal to the wallet that if a
|
||||||
|
// pending channel ID of expectedID is found, then it can skip constructing a
|
||||||
|
// new chanfunding.Assembler, and instead use the specified chanfunding.Intent.
|
||||||
|
// As an example, this lets some of the parameters for funding transaction to
|
||||||
|
// be negotiated outside the regular funding protocol.
|
||||||
|
func (l *LightningWallet) RegisterFundingIntent(expectedID [32]byte,
|
||||||
|
shimIntent chanfunding.Intent) error {
|
||||||
|
|
||||||
|
l.intentMtx.Lock()
|
||||||
|
l.fundingIntents[expectedID] = shimIntent
|
||||||
|
l.intentMtx.Unlock()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// handleFundingReserveRequest processes a message intending to create, and
|
// handleFundingReserveRequest processes a message intending to create, and
|
||||||
// validate a funding reservation request.
|
// validate a funding reservation request.
|
||||||
func (l *LightningWallet) handleFundingReserveRequest(req *InitFundingReserveMsg) {
|
func (l *LightningWallet) handleFundingReserveRequest(req *InitFundingReserveMsg) {
|
||||||
@@ -478,11 +499,19 @@ func (l *LightningWallet) handleFundingReserveRequest(req *InitFundingReserveMsg
|
|||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
// If we're on the receiving end of a single funder channel then we
|
// If we've just received an inbound funding request that we have a
|
||||||
// don't need to perform any coin selection, and the remote contributes
|
// registered shim intent to, then we'll obtain the backing intent now.
|
||||||
// all funds. Otherwise, attempt to obtain enough coins to meet the
|
// In this case, we're doing a special funding workflow that allows
|
||||||
// required funding amount.
|
// more advanced constructions such as channel factories to be
|
||||||
if req.LocalFundingAmt != 0 {
|
// instantiated.
|
||||||
|
l.intentMtx.Lock()
|
||||||
|
fundingIntent, ok := l.fundingIntents[req.PendingChanID]
|
||||||
|
l.intentMtx.Unlock()
|
||||||
|
|
||||||
|
// Otherwise, this is a normal funding flow, so we'll use the chan
|
||||||
|
// funder in the attached request to provision the inputs/outputs
|
||||||
|
// that'll ultimately be used to construct the funding transaction.
|
||||||
|
if !ok {
|
||||||
// Coin selection is done on the basis of sat/kw, so we'll use
|
// Coin selection is done on the basis of sat/kw, so we'll use
|
||||||
// the fee rate passed in to perform coin selection.
|
// the fee rate passed in to perform coin selection.
|
||||||
var err error
|
var err error
|
||||||
@@ -700,6 +729,16 @@ func (l *LightningWallet) handleFundingCancelRequest(req *fundingReserveCancelMs
|
|||||||
|
|
||||||
delete(l.fundingLimbo, req.pendingFundingID)
|
delete(l.fundingLimbo, req.pendingFundingID)
|
||||||
|
|
||||||
|
pid := pendingReservation.pendingChanID
|
||||||
|
|
||||||
|
l.intentMtx.Lock()
|
||||||
|
if intent, ok := l.fundingIntents[pid]; ok {
|
||||||
|
intent.Cancel()
|
||||||
|
|
||||||
|
delete(l.fundingIntents, pendingReservation.pendingChanID)
|
||||||
|
}
|
||||||
|
l.intentMtx.Unlock()
|
||||||
|
|
||||||
req.err <- nil
|
req.err <- nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1149,6 +1188,10 @@ func (l *LightningWallet) handleFundingCounterPartySigs(msg *addCounterPartySigs
|
|||||||
delete(l.fundingLimbo, res.reservationID)
|
delete(l.fundingLimbo, res.reservationID)
|
||||||
l.limboMtx.Unlock()
|
l.limboMtx.Unlock()
|
||||||
|
|
||||||
|
l.intentMtx.Lock()
|
||||||
|
delete(l.fundingIntents, res.pendingChanID)
|
||||||
|
l.intentMtx.Unlock()
|
||||||
|
|
||||||
// As we're about to broadcast the funding transaction, we'll take note
|
// As we're about to broadcast the funding transaction, we'll take note
|
||||||
// of the current height for record keeping purposes.
|
// of the current height for record keeping purposes.
|
||||||
//
|
//
|
||||||
@@ -1347,6 +1390,10 @@ func (l *LightningWallet) handleSingleFunderSigs(req *addSingleFunderSigsMsg) {
|
|||||||
l.limboMtx.Lock()
|
l.limboMtx.Lock()
|
||||||
delete(l.fundingLimbo, req.pendingFundingID)
|
delete(l.fundingLimbo, req.pendingFundingID)
|
||||||
l.limboMtx.Unlock()
|
l.limboMtx.Unlock()
|
||||||
|
|
||||||
|
l.intentMtx.Lock()
|
||||||
|
delete(l.fundingIntents, pendingReservation.pendingChanID)
|
||||||
|
l.intentMtx.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithCoinSelectLock will execute the passed function closure in a
|
// WithCoinSelectLock will execute the passed function closure in a
|
||||||
|
Reference in New Issue
Block a user