funding+lnwallet: validate ChannelReserve is above DustLimit
This is necessary and is implied by BOLT#02. Both ChannelReserve parameters should be above both DustLimit parameters. Otherwise, it is possible for one side to have nothing at stake.
This commit is contained in:
5 files changed
+81
-14
No files matched your search
+34
-2
@@ -394,7 +394,7 @@ func (r *ChannelReservation) SetNumConfsRequired(numConfs uint16) {
|
||||
// will also attempt to verify the constraints for sanity, returning an error
|
||||
// if the parameters are seemed unsound.
|
||||
func (r *ChannelReservation) CommitConstraints(c *channeldb.ChannelConstraints,
|
||||
maxLocalCSVDelay uint16) error {
|
||||
maxLocalCSVDelay uint16, responder bool) error {
|
||||
r.Lock()
|
||||
defer r.Unlock()
|
||||
|
||||
@@ -409,6 +409,13 @@ func (r *ChannelReservation) CommitConstraints(c *channeldb.ChannelConstraints,
|
||||
return ErrChanReserveTooSmall(c.ChanReserve, c.DustLimit)
|
||||
}
|
||||
|
||||
// Validate against the maximum-sized witness script dust limit, and
|
||||
// also ensure that the DustLimit is not too large.
|
||||
maxWitnessLimit := DustLimitForSize(input.UnknownWitnessSize)
|
||||
if c.DustLimit < maxWitnessLimit || c.DustLimit > 3*maxWitnessLimit {
|
||||
return ErrInvalidDustLimit(c.DustLimit)
|
||||
}
|
||||
|
||||
// Fail if we consider the channel reserve to be too large. We
|
||||
// currently fail if it is greater than 20% of the channel capacity.
|
||||
maxChanReserve := r.partialState.Capacity / 5
|
||||
@@ -449,7 +456,7 @@ func (r *ChannelReservation) CommitConstraints(c *channeldb.ChannelConstraints,
|
||||
|
||||
// Our dust limit should always be less than or equal to our proposed
|
||||
// channel reserve.
|
||||
if r.ourContribution.DustLimit > c.ChanReserve {
|
||||
if responder && r.ourContribution.DustLimit > c.ChanReserve {
|
||||
r.ourContribution.DustLimit = c.ChanReserve
|
||||
}
|
||||
|
||||
@@ -462,6 +469,31 @@ func (r *ChannelReservation) CommitConstraints(c *channeldb.ChannelConstraints,
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateReserveBounds checks that both ChannelReserve values are above both
|
||||
// DustLimit values. This not only avoids stuck channels, but is also mandated
|
||||
// by BOLT#02 even if it's not explicit. This returns true if the bounds are
|
||||
// valid. This function should be called with the lock held.
|
||||
func (r *ChannelReservation) validateReserveBounds() bool {
|
||||
ourDustLimit := r.ourContribution.DustLimit
|
||||
ourRequiredReserve := r.ourContribution.ChanReserve
|
||||
theirDustLimit := r.theirContribution.DustLimit
|
||||
theirRequiredReserve := r.theirContribution.ChanReserve
|
||||
|
||||
// We take the smaller of the two ChannelReserves and compare it
|
||||
// against the larger of the two DustLimits.
|
||||
minChanReserve := ourRequiredReserve
|
||||
if minChanReserve > theirRequiredReserve {
|
||||
minChanReserve = theirRequiredReserve
|
||||
}
|
||||
|
||||
maxDustLimit := ourDustLimit
|
||||
if maxDustLimit < theirDustLimit {
|
||||
maxDustLimit = theirDustLimit
|
||||
}
|
||||
|
||||
return minChanReserve >= maxDustLimit
|
||||
}
|
||||
|
||||
// OurContribution returns the wallet's fully populated contribution to the
|
||||
// pending payment channel. See 'ChannelContribution' for further details
|
||||
// regarding the contents of a contribution.
|
||||
|
||||
Reference in new issue
Block a user