lnwallet+fundingmanager: use ChannelConstraints struct with CommitConstraints

This commit is contained in:
Wilmer Paulino 2018-12-10 13:58:34 -08:00
parent b951f06456
commit 71410f6a08
No known key found for this signature in database
GPG Key ID: 6DF57B9F9514972F
3 changed files with 71 additions and 61 deletions

@ -1072,20 +1072,25 @@ func (f *fundingManager) handleFundingOpen(fmsg *fundingOpenMsg) {
return return
} }
// As we're the responder, we get to specify the number of // As we're the responder, we get to specify the number of confirmations
// confirmations that we require before both of us consider the channel // that we require before both of us consider the channel open. We'll
// open. We'll use out mapping to derive the proper number of // use out mapping to derive the proper number of confirmations based on
// confirmations based on the amount of the channel, and also if any // the amount of the channel, and also if any funds are being pushed to
// funds are being pushed to us. // us.
numConfsReq := f.cfg.NumRequiredConfs(msg.FundingAmount, msg.PushAmount) numConfsReq := f.cfg.NumRequiredConfs(msg.FundingAmount, msg.PushAmount)
reservation.SetNumConfsRequired(numConfsReq) reservation.SetNumConfsRequired(numConfsReq)
// We'll also validate and apply all the constraints the initiating // We'll also validate and apply all the constraints the initiating
// party is attempting to dictate for our commitment transaction. // party is attempting to dictate for our commitment transaction.
err = reservation.CommitConstraints( channelConstraints := &channeldb.ChannelConstraints{
msg.CsvDelay, msg.MaxAcceptedHTLCs, msg.MaxValueInFlight, DustLimit: msg.DustLimit,
msg.HtlcMinimum, msg.ChannelReserve, msg.DustLimit, ChanReserve: msg.ChannelReserve,
) MaxPendingAmount: msg.MaxValueInFlight,
MinHTLC: msg.HtlcMinimum,
MaxAcceptedHtlcs: msg.MaxAcceptedHTLCs,
CsvDelay: msg.CsvDelay,
}
err = reservation.CommitConstraints(channelConstraints)
if err != nil { if err != nil {
fndgLog.Errorf("Unacceptable channel constraints: %v", err) fndgLog.Errorf("Unacceptable channel constraints: %v", err)
f.failFundingFlow(fmsg.peer, fmsg.msg.PendingChannelID, err) f.failFundingFlow(fmsg.peer, fmsg.msg.PendingChannelID, err)
@ -1229,10 +1234,15 @@ func (f *fundingManager) handleFundingAccept(fmsg *fundingAcceptMsg) {
// required confirmations, and also the set of channel constraints // required confirmations, and also the set of channel constraints
// they've specified for commitment states we can create. // they've specified for commitment states we can create.
resCtx.reservation.SetNumConfsRequired(uint16(msg.MinAcceptDepth)) resCtx.reservation.SetNumConfsRequired(uint16(msg.MinAcceptDepth))
err = resCtx.reservation.CommitConstraints( channelConstraints := &channeldb.ChannelConstraints{
msg.CsvDelay, msg.MaxAcceptedHTLCs, msg.MaxValueInFlight, DustLimit: msg.DustLimit,
msg.HtlcMinimum, msg.ChannelReserve, msg.DustLimit, ChanReserve: msg.ChannelReserve,
) MaxPendingAmount: msg.MaxValueInFlight,
MinHTLC: msg.HtlcMinimum,
MaxAcceptedHtlcs: msg.MaxAcceptedHTLCs,
CsvDelay: msg.CsvDelay,
}
err = resCtx.reservation.CommitConstraints(channelConstraints)
if err != nil { if err != nil {
fndgLog.Warnf("Unacceptable channel constraints: %v", err) fndgLog.Warnf("Unacceptable channel constraints: %v", err)
f.failFundingFlow(fmsg.peer, fmsg.msg.PendingChannelID, err) f.failFundingFlow(fmsg.peer, fmsg.msg.PendingChannelID, err)
@ -1860,7 +1870,7 @@ func (f *fundingManager) waitForFundingConfirmation(completeChan *channeldb.Open
) )
if err != nil { if err != nil {
fndgLog.Errorf("Unable to register for confirmation of "+ fndgLog.Errorf("Unable to register for confirmation of "+
"ChannelPoint(%v)", completeChan.FundingOutpoint) "ChannelPoint(%v): %v", completeChan.FundingOutpoint, err)
return return
} }

@ -429,11 +429,15 @@ func testDualFundingReservationWorkflow(miner *rpctest.Harness,
t.Fatalf("unable to initialize funding reservation: %v", err) t.Fatalf("unable to initialize funding reservation: %v", err)
} }
aliceChanReservation.SetNumConfsRequired(numReqConfs) aliceChanReservation.SetNumConfsRequired(numReqConfs)
err = aliceChanReservation.CommitConstraints( channelConstraints := &channeldb.ChannelConstraints{
csvDelay, lnwallet.MaxHTLCNumber/2, DustLimit: lnwallet.DefaultDustLimit(),
lnwire.NewMSatFromSatoshis(fundingAmount), 1, fundingAmount/100, ChanReserve: fundingAmount / 100,
lnwallet.DefaultDustLimit(), MaxPendingAmount: lnwire.NewMSatFromSatoshis(fundingAmount),
) MinHTLC: 1,
MaxAcceptedHtlcs: lnwallet.MaxHTLCNumber / 2,
CsvDelay: csvDelay,
}
err = aliceChanReservation.CommitConstraints(channelConstraints)
if err != nil { if err != nil {
t.Fatalf("unable to verify constraints: %v", err) t.Fatalf("unable to verify constraints: %v", err)
} }
@ -467,11 +471,7 @@ func testDualFundingReservationWorkflow(miner *rpctest.Harness,
if err != nil { if err != nil {
t.Fatalf("bob unable to init channel reservation: %v", err) t.Fatalf("bob unable to init channel reservation: %v", err)
} }
err = bobChanReservation.CommitConstraints( err = bobChanReservation.CommitConstraints(channelConstraints)
csvDelay, lnwallet.MaxHTLCNumber/2,
lnwire.NewMSatFromSatoshis(fundingAmount), 1, fundingAmount/100,
lnwallet.DefaultDustLimit(),
)
if err != nil { if err != nil {
t.Fatalf("unable to verify constraints: %v", err) t.Fatalf("unable to verify constraints: %v", err)
} }
@ -861,11 +861,15 @@ func testSingleFunderReservationWorkflow(miner *rpctest.Harness,
t.Fatalf("unable to init channel reservation: %v", err) t.Fatalf("unable to init channel reservation: %v", err)
} }
aliceChanReservation.SetNumConfsRequired(numReqConfs) aliceChanReservation.SetNumConfsRequired(numReqConfs)
err = aliceChanReservation.CommitConstraints( channelConstraints := &channeldb.ChannelConstraints{
csvDelay, lnwallet.MaxHTLCNumber/2, DustLimit: lnwallet.DefaultDustLimit(),
lnwire.NewMSatFromSatoshis(fundingAmt), 1, fundingAmt/100, ChanReserve: fundingAmt / 100,
lnwallet.DefaultDustLimit(), MaxPendingAmount: lnwire.NewMSatFromSatoshis(fundingAmt),
) MinHTLC: 1,
MaxAcceptedHtlcs: lnwallet.MaxHTLCNumber / 2,
CsvDelay: csvDelay,
}
err = aliceChanReservation.CommitConstraints(channelConstraints)
if err != nil { if err != nil {
t.Fatalf("unable to verify constraints: %v", err) t.Fatalf("unable to verify constraints: %v", err)
} }
@ -899,11 +903,7 @@ func testSingleFunderReservationWorkflow(miner *rpctest.Harness,
if err != nil { if err != nil {
t.Fatalf("unable to create bob reservation: %v", err) t.Fatalf("unable to create bob reservation: %v", err)
} }
err = bobChanReservation.CommitConstraints( err = bobChanReservation.CommitConstraints(channelConstraints)
csvDelay, lnwallet.MaxHTLCNumber/2,
lnwire.NewMSatFromSatoshis(fundingAmt), 1, fundingAmt/100,
lnwallet.DefaultDustLimit(),
)
if err != nil { if err != nil {
t.Fatalf("unable to verify constraints: %v", err) t.Fatalf("unable to verify constraints: %v", err)
} }

@ -282,72 +282,72 @@ func (r *ChannelReservation) SetNumConfsRequired(numConfs uint16) {
// of satoshis that can be transferred in a single commitment. This function // of satoshis that can be transferred in a single commitment. This function
// will also attempt to verify the constraints for sanity, returning an error // will also attempt to verify the constraints for sanity, returning an error
// if the parameters are seemed unsound. // if the parameters are seemed unsound.
func (r *ChannelReservation) CommitConstraints(csvDelay, maxHtlcs uint16, func (r *ChannelReservation) CommitConstraints(c *channeldb.ChannelConstraints) error {
maxValueInFlight, minHtlc lnwire.MilliSatoshi,
chanReserve, dustLimit btcutil.Amount) error {
r.Lock() r.Lock()
defer r.Unlock() defer r.Unlock()
// Fail if we consider csvDelay excessively large. // Fail if we consider csvDelay excessively large.
// TODO(halseth): find a more scientific choice of value. // TODO(halseth): find a more scientific choice of value.
const maxDelay = 10000 const maxDelay = 10000
if csvDelay > maxDelay { if c.CsvDelay > maxDelay {
return ErrCsvDelayTooLarge(csvDelay, maxDelay) return ErrCsvDelayTooLarge(c.CsvDelay, maxDelay)
} }
// The dust limit should always be greater or equal to the channel // The dust limit should always be greater or equal to the channel
// reserve. The reservation request should be denied if otherwise. // reserve. The reservation request should be denied if otherwise.
if dustLimit > chanReserve { if c.DustLimit > c.ChanReserve {
return ErrChanReserveTooSmall(chanReserve, dustLimit) return ErrChanReserveTooSmall(c.ChanReserve, c.DustLimit)
} }
// Fail if we consider the channel reserve to be too large. We // Fail if we consider the channel reserve to be too large. We
// currently fail if it is greater than 20% of the channel capacity. // currently fail if it is greater than 20% of the channel capacity.
maxChanReserve := r.partialState.Capacity / 5 maxChanReserve := r.partialState.Capacity / 5
if chanReserve > maxChanReserve { if c.ChanReserve > maxChanReserve {
return ErrChanReserveTooLarge(chanReserve, maxChanReserve) return ErrChanReserveTooLarge(c.ChanReserve, maxChanReserve)
} }
// Fail if the minimum HTLC value is too large. If this is too large, // Fail if the minimum HTLC value is too large. If this is too large,
// the channel won't be useful for sending small payments. This limit // the channel won't be useful for sending small payments. This limit
// is currently set to maxValueInFlight, effectively letting the remote // is currently set to maxValueInFlight, effectively letting the remote
// setting this as large as it wants. // setting this as large as it wants.
if minHtlc > maxValueInFlight { if c.MinHTLC > c.MaxPendingAmount {
return ErrMinHtlcTooLarge(minHtlc, maxValueInFlight) return ErrMinHtlcTooLarge(c.MinHTLC, c.MaxPendingAmount)
} }
// Fail if maxHtlcs is above the maximum allowed number of 483. This // Fail if maxHtlcs is above the maximum allowed number of 483. This
// number is specified in BOLT-02. // number is specified in BOLT-02.
if maxHtlcs > uint16(MaxHTLCNumber/2) { if c.MaxAcceptedHtlcs > uint16(MaxHTLCNumber/2) {
return ErrMaxHtlcNumTooLarge(maxHtlcs, uint16(MaxHTLCNumber/2)) return ErrMaxHtlcNumTooLarge(
c.MaxAcceptedHtlcs, uint16(MaxHTLCNumber/2),
)
} }
// Fail if we consider maxHtlcs too small. If this is too small we // Fail if we consider maxHtlcs too small. If this is too small we
// cannot offer many HTLCs to the remote. // cannot offer many HTLCs to the remote.
const minNumHtlc = 5 const minNumHtlc = 5
if maxHtlcs < minNumHtlc { if c.MaxAcceptedHtlcs < minNumHtlc {
return ErrMaxHtlcNumTooSmall(maxHtlcs, minNumHtlc) return ErrMaxHtlcNumTooSmall(c.MaxAcceptedHtlcs, minNumHtlc)
} }
// Fail if we consider maxValueInFlight too small. We currently require // Fail if we consider maxValueInFlight too small. We currently require
// the remote to at least allow minNumHtlc * minHtlc in flight. // the remote to at least allow minNumHtlc * minHtlc in flight.
if maxValueInFlight < minNumHtlc*minHtlc { if c.MaxPendingAmount < minNumHtlc*c.MinHTLC {
return ErrMaxValueInFlightTooSmall(maxValueInFlight, return ErrMaxValueInFlightTooSmall(
minNumHtlc*minHtlc) c.MaxPendingAmount, minNumHtlc*c.MinHTLC,
)
} }
// Our dust limit should always be less than or equal our proposed // Our dust limit should always be less than or equal to our proposed
// channel reserve. // channel reserve.
if r.ourContribution.DustLimit > chanReserve { if r.ourContribution.DustLimit > c.ChanReserve {
r.ourContribution.DustLimit = chanReserve r.ourContribution.DustLimit = c.ChanReserve
} }
r.ourContribution.ChannelConfig.CsvDelay = csvDelay r.ourContribution.ChanReserve = c.ChanReserve
r.ourContribution.ChannelConfig.ChanReserve = chanReserve r.ourContribution.MaxPendingAmount = c.MaxPendingAmount
r.ourContribution.ChannelConfig.MaxAcceptedHtlcs = maxHtlcs r.ourContribution.MinHTLC = c.MinHTLC
r.ourContribution.ChannelConfig.MaxPendingAmount = maxValueInFlight r.ourContribution.MaxAcceptedHtlcs = c.MaxAcceptedHtlcs
r.ourContribution.ChannelConfig.MinHTLC = minHtlc r.ourContribution.CsvDelay = c.CsvDelay
return nil return nil
} }