mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-06-30 10:35:32 +02:00
lnd: handles the FundMax
field inside parseOpenChannelReq
Adds handling of the `FundMax` field when parsing an `OpenChannelRequest` with `rpcServer.parseOpenChannelReq`.
This commit is contained in:
committed by
Slyghtning
parent
e82410d24a
commit
0e5b3e77cb
@ -266,6 +266,15 @@ type InitFundingMsg struct {
|
|||||||
// peer.
|
// peer.
|
||||||
MaxLocalCsv uint16
|
MaxLocalCsv uint16
|
||||||
|
|
||||||
|
// FundUpToMaxAmt is the maximum amount to try to commit to. If set, the
|
||||||
|
// MinFundAmt field denotes the acceptable minimum amount to commit to,
|
||||||
|
// while trying to commit as many coins as possible up to this value.
|
||||||
|
FundUpToMaxAmt btcutil.Amount
|
||||||
|
|
||||||
|
// MinFundAmt must be set iff FundUpToMaxAmt is set. It denotes the
|
||||||
|
// minimum amount to commit to.
|
||||||
|
MinFundAmt btcutil.Amount
|
||||||
|
|
||||||
// ChanFunder is an optional channel funder that allows the caller to
|
// ChanFunder is an optional channel funder that allows the caller to
|
||||||
// control exactly how the channel funding is carried out. If not
|
// control exactly how the channel funding is carried out. If not
|
||||||
// specified, then the default chanfunding.WalletAssembler will be
|
// specified, then the default chanfunding.WalletAssembler will be
|
||||||
|
103
rpcserver.go
103
rpcserver.go
@ -1934,6 +1934,62 @@ func (r *rpcServer) parseOpenChannelReq(in *lnrpc.OpenChannelRequest,
|
|||||||
|
|
||||||
localFundingAmt := btcutil.Amount(in.LocalFundingAmount)
|
localFundingAmt := btcutil.Amount(in.LocalFundingAmount)
|
||||||
remoteInitialBalance := btcutil.Amount(in.PushSat)
|
remoteInitialBalance := btcutil.Amount(in.PushSat)
|
||||||
|
|
||||||
|
// If we are not committing the maximum viable balance towards a channel
|
||||||
|
// then the local funding amount must be specified. In case FundMax is
|
||||||
|
// set the funding amount is specified as the interval between minimum
|
||||||
|
// funding amount and by the configured maximum channel size.
|
||||||
|
if !in.FundMax && localFundingAmt == 0 {
|
||||||
|
return nil, fmt.Errorf("local funding amount must be non-zero")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure that the initial balance of the remote party (if pushing
|
||||||
|
// satoshis) does not exceed the amount the local party has requested
|
||||||
|
// for funding. This is only checked if we are not committing the
|
||||||
|
// maximum viable amount towards the channel balance. If we do commit
|
||||||
|
// the maximum then the remote balance is checked in a dedicated FundMax
|
||||||
|
// check.
|
||||||
|
if !in.FundMax && remoteInitialBalance >= localFundingAmt {
|
||||||
|
return nil, fmt.Errorf("amount pushed to remote peer for " +
|
||||||
|
"initial state must be below the local funding amount")
|
||||||
|
}
|
||||||
|
|
||||||
|
// We either allow the fundmax or the psbt flow hence we return an error
|
||||||
|
// if both are set.
|
||||||
|
if in.FundingShim != nil && in.FundMax {
|
||||||
|
return nil, fmt.Errorf("cannot provide a psbt funding shim " +
|
||||||
|
"while committing the maxium wallet balance towards " +
|
||||||
|
"the channel opening")
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the FundMax flag is set, ensure that the acceptable minimum local
|
||||||
|
// amount adheres to the amount to be pushed to the remote, and to
|
||||||
|
// current rules, while also respecting the settings for the maximum
|
||||||
|
// channel size.
|
||||||
|
var minFundAmt, fundUpToMaxAmt btcutil.Amount
|
||||||
|
if in.FundMax {
|
||||||
|
// We assume the configured maximum channel size to be the upper
|
||||||
|
// bound of our "maxed" out funding attempt.
|
||||||
|
fundUpToMaxAmt = btcutil.Amount(r.cfg.MaxChanSize)
|
||||||
|
|
||||||
|
// Since the standard non-fundmax flow requires the minimum
|
||||||
|
// funding amount to be at least in the amount of the initial
|
||||||
|
// remote balance(push amount) we need to adjust the minimum
|
||||||
|
// funding amount accordingly. We initially assume the minimum
|
||||||
|
// allowed channel size as minimum funding amount.
|
||||||
|
minFundAmt = funding.MinChanFundingSize
|
||||||
|
|
||||||
|
// If minFundAmt is less than the initial remote balance we
|
||||||
|
// simply assign the initial remote balance to minFundAmt in
|
||||||
|
// order to fullfil the criterion. Whether or not this so
|
||||||
|
// determined minimum amount is actually available is
|
||||||
|
// ascertained downstream in the lnwallet's reservation
|
||||||
|
// workflow.
|
||||||
|
if remoteInitialBalance >= minFundAmt {
|
||||||
|
minFundAmt = remoteInitialBalance
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
minHtlcIn := lnwire.MilliSatoshi(in.MinHtlcMsat)
|
minHtlcIn := lnwire.MilliSatoshi(in.MinHtlcMsat)
|
||||||
remoteCsvDelay := uint16(in.RemoteCsvDelay)
|
remoteCsvDelay := uint16(in.RemoteCsvDelay)
|
||||||
maxValue := lnwire.MilliSatoshi(in.RemoteMaxValueInFlightMsat)
|
maxValue := lnwire.MilliSatoshi(in.RemoteMaxValueInFlightMsat)
|
||||||
@ -1942,20 +1998,6 @@ func (r *rpcServer) parseOpenChannelReq(in *lnrpc.OpenChannelRequest,
|
|||||||
|
|
||||||
globalFeatureSet := r.server.featureMgr.Get(feature.SetNodeAnn)
|
globalFeatureSet := r.server.featureMgr.Get(feature.SetNodeAnn)
|
||||||
|
|
||||||
// Ensure that a local funding amount has been specified.
|
|
||||||
if localFundingAmt == 0 {
|
|
||||||
return nil, fmt.Errorf("local funding amount must be non-zero")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure that the initial balance of the remote party (if pushing
|
|
||||||
// satoshis) does not exceed the amount the local party has requested
|
|
||||||
// for funding.
|
|
||||||
//
|
|
||||||
if remoteInitialBalance >= localFundingAmt {
|
|
||||||
return nil, fmt.Errorf("amount pushed to remote peer for " +
|
|
||||||
"initial state must be below the local funding amount")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determine if the user provided channel fees
|
// Determine if the user provided channel fees
|
||||||
// and if so pass them on to the funding workflow.
|
// and if so pass them on to the funding workflow.
|
||||||
var channelBaseFee, channelFeeRate *uint64
|
var channelBaseFee, channelFeeRate *uint64
|
||||||
@ -1968,7 +2010,7 @@ func (r *rpcServer) parseOpenChannelReq(in *lnrpc.OpenChannelRequest,
|
|||||||
|
|
||||||
// Ensure that the remote channel reserve does not exceed 20% of the
|
// Ensure that the remote channel reserve does not exceed 20% of the
|
||||||
// channel capacity.
|
// channel capacity.
|
||||||
if remoteChanReserve >= localFundingAmt/5 {
|
if !in.FundMax && remoteChanReserve >= localFundingAmt/5 {
|
||||||
return nil, fmt.Errorf("remote channel reserve must be less " +
|
return nil, fmt.Errorf("remote channel reserve must be less " +
|
||||||
"than the %%20 of the channel capacity")
|
"than the %%20 of the channel capacity")
|
||||||
}
|
}
|
||||||
@ -1976,18 +2018,25 @@ func (r *rpcServer) parseOpenChannelReq(in *lnrpc.OpenChannelRequest,
|
|||||||
// Ensure that the user doesn't exceed the current soft-limit for
|
// Ensure that the user doesn't exceed the current soft-limit for
|
||||||
// channel size. If the funding amount is above the soft-limit, then
|
// channel size. If the funding amount is above the soft-limit, then
|
||||||
// we'll reject the request.
|
// we'll reject the request.
|
||||||
|
// If the FundMax flag is set the local amount is determined downstream
|
||||||
|
// in the wallet hence we do not check it here against the maximum
|
||||||
|
// funding amount. Only if the localFundingAmt is specified we can check
|
||||||
|
// if it exceeds the maximum funding amount.
|
||||||
wumboEnabled := globalFeatureSet.HasFeature(
|
wumboEnabled := globalFeatureSet.HasFeature(
|
||||||
lnwire.WumboChannelsOptional,
|
lnwire.WumboChannelsOptional,
|
||||||
)
|
)
|
||||||
if !wumboEnabled && localFundingAmt > MaxFundingAmount {
|
if !in.FundMax && !wumboEnabled && localFundingAmt > MaxFundingAmount {
|
||||||
return nil, fmt.Errorf("funding amount is too large, the max "+
|
return nil, fmt.Errorf("funding amount is too large, the max "+
|
||||||
"channel size is: %v", MaxFundingAmount)
|
"channel size is: %v", MaxFundingAmount)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restrict the size of the channel we'll actually open. At a later
|
// Restrict the size of the channel we'll actually open. At a later
|
||||||
// level, we'll ensure that the output we create after accounting for
|
// level, we'll ensure that the output we create, after accounting for
|
||||||
// fees that a dust output isn't created.
|
// fees, does not leave a dust output. In case of the FundMax flow
|
||||||
if localFundingAmt < funding.MinChanFundingSize {
|
// dedicated checks ensure that the lower boundary of the channel size
|
||||||
|
// is at least in the amount of MinChanFundingSize or potentially higher
|
||||||
|
// if a remote balance is specified.
|
||||||
|
if !in.FundMax && localFundingAmt < funding.MinChanFundingSize {
|
||||||
return nil, fmt.Errorf("channel is too small, the minimum "+
|
return nil, fmt.Errorf("channel is too small, the minimum "+
|
||||||
"channel size is: %v SAT", int64(funding.MinChanFundingSize))
|
"channel size is: %v SAT", int64(funding.MinChanFundingSize))
|
||||||
}
|
}
|
||||||
@ -2128,12 +2177,14 @@ func (r *rpcServer) parseOpenChannelReq(in *lnrpc.OpenChannelRequest,
|
|||||||
// open a new channel. A stream is returned in place, this stream will
|
// open a new channel. A stream is returned in place, this stream will
|
||||||
// be used to consume updates of the state of the pending channel.
|
// be used to consume updates of the state of the pending channel.
|
||||||
return &funding.InitFundingMsg{
|
return &funding.InitFundingMsg{
|
||||||
TargetPubkey: nodePubKey,
|
TargetPubkey: nodePubKey,
|
||||||
ChainHash: *r.cfg.ActiveNetParams.GenesisHash,
|
ChainHash: *r.cfg.ActiveNetParams.GenesisHash,
|
||||||
LocalFundingAmt: localFundingAmt,
|
LocalFundingAmt: localFundingAmt,
|
||||||
BaseFee: channelBaseFee,
|
BaseFee: channelBaseFee,
|
||||||
FeeRate: channelFeeRate,
|
FeeRate: channelFeeRate,
|
||||||
PushAmt: lnwire.NewMSatFromSatoshis(remoteInitialBalance),
|
PushAmt: lnwire.NewMSatFromSatoshis(
|
||||||
|
remoteInitialBalance,
|
||||||
|
),
|
||||||
MinHtlcIn: minHtlcIn,
|
MinHtlcIn: minHtlcIn,
|
||||||
FundingFeePerKw: feeRate,
|
FundingFeePerKw: feeRate,
|
||||||
Private: in.Private,
|
Private: in.Private,
|
||||||
@ -2145,6 +2196,8 @@ func (r *rpcServer) parseOpenChannelReq(in *lnrpc.OpenChannelRequest,
|
|||||||
MaxHtlcs: maxHtlcs,
|
MaxHtlcs: maxHtlcs,
|
||||||
MaxLocalCsv: uint16(in.MaxLocalCsv),
|
MaxLocalCsv: uint16(in.MaxLocalCsv),
|
||||||
ChannelType: channelType,
|
ChannelType: channelType,
|
||||||
|
FundUpToMaxAmt: fundUpToMaxAmt,
|
||||||
|
MinFundAmt: minFundAmt,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user