fundingmanager+lnwallet: ensure proposed channel reserve is above dust limit
This commit is contained in:
parent
2e076ba21e
commit
3a982063a0
@ -994,10 +994,10 @@ func (f *fundingManager) handleFundingOpen(fmsg *fundingOpenMsg) {
|
||||
// party is attempting to dictate for our commitment transaction.
|
||||
err = reservation.CommitConstraints(
|
||||
msg.CsvDelay, msg.MaxAcceptedHTLCs, msg.MaxValueInFlight,
|
||||
msg.HtlcMinimum, msg.ChannelReserve,
|
||||
msg.HtlcMinimum, msg.ChannelReserve, msg.DustLimit,
|
||||
)
|
||||
if err != nil {
|
||||
fndgLog.Errorf("Unaccaptable channel constraints: %v", err)
|
||||
fndgLog.Errorf("Unacceptable channel constraints: %v", err)
|
||||
f.failFundingFlow(fmsg.peerAddress.IdentityKey,
|
||||
fmsg.msg.PendingChannelID, err,
|
||||
)
|
||||
@ -1146,7 +1146,7 @@ func (f *fundingManager) handleFundingAccept(fmsg *fundingAcceptMsg) {
|
||||
resCtx.reservation.SetNumConfsRequired(uint16(msg.MinAcceptDepth))
|
||||
err = resCtx.reservation.CommitConstraints(
|
||||
msg.CsvDelay, msg.MaxAcceptedHTLCs, msg.MaxValueInFlight,
|
||||
msg.HtlcMinimum, msg.ChannelReserve,
|
||||
msg.HtlcMinimum, msg.ChannelReserve, msg.DustLimit,
|
||||
)
|
||||
if err != nil {
|
||||
fndgLog.Warnf("Unacceptable channel constraints: %v", err)
|
||||
|
@ -59,6 +59,15 @@ func ErrCsvDelayTooLarge(remoteDelay, maxDelay uint16) ReservationError {
|
||||
}
|
||||
}
|
||||
|
||||
// ErrChanReserveTooSmall returns an error indicating that the channel reserve
|
||||
// the remote is requiring is too small to be accepted.
|
||||
func ErrChanReserveTooSmall(reserve, dustLimit btcutil.Amount) ReservationError {
|
||||
return ReservationError{
|
||||
fmt.Errorf("channel reserve of %v sat is too small, min is %v "+
|
||||
"sat", int64(reserve), int64(dustLimit)),
|
||||
}
|
||||
}
|
||||
|
||||
// ErrChanReserveTooLarge returns an error indicating that the chan reserve the
|
||||
// remote is requiring, is too large to be accepted.
|
||||
func ErrChanReserveTooLarge(reserve,
|
||||
|
@ -305,8 +305,14 @@ func testDualFundingReservationWorkflow(miner *rpctest.Harness,
|
||||
t.Fatalf("unable to initialize funding reservation: %v", err)
|
||||
}
|
||||
aliceChanReservation.SetNumConfsRequired(numReqConfs)
|
||||
aliceChanReservation.CommitConstraints(csvDelay, lnwallet.MaxHTLCNumber/2,
|
||||
lnwire.NewMSatFromSatoshis(fundingAmount), 1, 10)
|
||||
err = aliceChanReservation.CommitConstraints(
|
||||
csvDelay, lnwallet.MaxHTLCNumber/2,
|
||||
lnwire.NewMSatFromSatoshis(fundingAmount), 1, fundingAmount/100,
|
||||
lnwallet.DefaultDustLimit(),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to verify constraints: %v", err)
|
||||
}
|
||||
|
||||
// The channel reservation should now be populated with a multi-sig key
|
||||
// from our HD chain, a change output with 3 BTC, and 2 outputs
|
||||
@ -328,8 +334,14 @@ func testDualFundingReservationWorkflow(miner *rpctest.Harness,
|
||||
if err != nil {
|
||||
t.Fatalf("bob unable to init channel reservation: %v", err)
|
||||
}
|
||||
bobChanReservation.CommitConstraints(csvDelay, lnwallet.MaxHTLCNumber/2,
|
||||
lnwire.NewMSatFromSatoshis(fundingAmount), 1, 10)
|
||||
err = bobChanReservation.CommitConstraints(
|
||||
csvDelay, lnwallet.MaxHTLCNumber/2,
|
||||
lnwire.NewMSatFromSatoshis(fundingAmount), 1, fundingAmount/100,
|
||||
lnwallet.DefaultDustLimit(),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to verify constraints: %v", err)
|
||||
}
|
||||
bobChanReservation.SetNumConfsRequired(numReqConfs)
|
||||
|
||||
assertContributionInitPopulated(t, bobChanReservation.OurContribution())
|
||||
@ -675,8 +687,14 @@ func testSingleFunderReservationWorkflow(miner *rpctest.Harness,
|
||||
t.Fatalf("unable to init channel reservation: %v", err)
|
||||
}
|
||||
aliceChanReservation.SetNumConfsRequired(numReqConfs)
|
||||
aliceChanReservation.CommitConstraints(csvDelay, lnwallet.MaxHTLCNumber/2,
|
||||
lnwire.NewMSatFromSatoshis(fundingAmt), 1, 10)
|
||||
err = aliceChanReservation.CommitConstraints(
|
||||
csvDelay, lnwallet.MaxHTLCNumber/2,
|
||||
lnwire.NewMSatFromSatoshis(fundingAmt), 1, fundingAmt/100,
|
||||
lnwallet.DefaultDustLimit(),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to verify constraints: %v", err)
|
||||
}
|
||||
|
||||
// Verify all contribution fields have been set properly.
|
||||
aliceContribution := aliceChanReservation.OurContribution()
|
||||
@ -698,8 +716,14 @@ func testSingleFunderReservationWorkflow(miner *rpctest.Harness,
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create bob reservation: %v", err)
|
||||
}
|
||||
bobChanReservation.CommitConstraints(csvDelay, lnwallet.MaxHTLCNumber/2,
|
||||
lnwire.NewMSatFromSatoshis(fundingAmt), 1, 10)
|
||||
err = bobChanReservation.CommitConstraints(
|
||||
csvDelay, lnwallet.MaxHTLCNumber/2,
|
||||
lnwire.NewMSatFromSatoshis(fundingAmt), 1, fundingAmt/100,
|
||||
lnwallet.DefaultDustLimit(),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to verify constraints: %v", err)
|
||||
}
|
||||
bobChanReservation.SetNumConfsRequired(numReqConfs)
|
||||
|
||||
// We'll ensure that Bob's contribution also gets generated properly.
|
||||
|
@ -284,7 +284,7 @@ func (r *ChannelReservation) SetNumConfsRequired(numConfs uint16) {
|
||||
// if the parameters are seemed unsound.
|
||||
func (r *ChannelReservation) CommitConstraints(csvDelay, maxHtlcs uint16,
|
||||
maxValueInFlight, minHtlc lnwire.MilliSatoshi,
|
||||
chanReserve btcutil.Amount) error {
|
||||
chanReserve, dustLimit btcutil.Amount) error {
|
||||
|
||||
r.Lock()
|
||||
defer r.Unlock()
|
||||
@ -296,6 +296,12 @@ func (r *ChannelReservation) CommitConstraints(csvDelay, maxHtlcs uint16,
|
||||
return ErrCsvDelayTooLarge(csvDelay, maxDelay)
|
||||
}
|
||||
|
||||
// The dust limit should always be greater or equal to the channel
|
||||
// reserve. The reservation request should be denied if otherwise.
|
||||
if dustLimit > chanReserve {
|
||||
return ErrChanReserveTooSmall(chanReserve, 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
|
||||
@ -331,6 +337,12 @@ func (r *ChannelReservation) CommitConstraints(csvDelay, maxHtlcs uint16,
|
||||
minNumHtlc*minHtlc)
|
||||
}
|
||||
|
||||
// Our dust limit should always be less than or equal our proposed
|
||||
// channel reserve.
|
||||
if r.ourContribution.DustLimit > chanReserve {
|
||||
r.ourContribution.DustLimit = chanReserve
|
||||
}
|
||||
|
||||
r.ourContribution.ChannelConfig.CsvDelay = csvDelay
|
||||
r.ourContribution.ChannelConfig.ChanReserve = chanReserve
|
||||
r.ourContribution.ChannelConfig.MaxAcceptedHtlcs = maxHtlcs
|
||||
|
Loading…
Reference in New Issue
Block a user