diff --git a/fundingmanager.go b/fundingmanager.go index 4614c18b0..d3440b699 100644 --- a/fundingmanager.go +++ b/fundingmanager.go @@ -689,21 +689,40 @@ func (f *fundingManager) CancelPeerReservations(nodePub [33]byte) { } // failFundingFlow will fail the active funding flow with the target peer, -// identified by its unique temporary channel ID. This method is send an error -// to the remote peer, and also remove the reservation from our set of pending -// reservations. +// identified by its unique temporary channel ID. This method will send an +// error to the remote peer, and also remove the reservation from our set of +// pending reservations. // // TODO(roasbeef): if peer disconnects, and haven't yet broadcast funding // transaction, then all reservations should be cleared. func (f *fundingManager) failFundingFlow(peer *btcec.PublicKey, - tempChanID [32]byte, msg []byte) { + tempChanID [32]byte, fundingErr error) { + + // We only send the exact error if it is part of out whitelisted set of + // errors (lnwire.ErrorCode or lnwallet.ReservationError). + var msg lnwire.ErrorData + switch e := fundingErr.(type) { + + // Let the actual error message be sent to the remote. + case lnwallet.ReservationError: + msg = lnwire.ErrorData(e.Error()) + + // Send the status code. + case lnwire.ErrorCode: + msg = lnwire.ErrorData{byte(e)} + + // We just send a generic error. + default: + msg = lnwire.ErrorData("funding failed due to internal error") + } errMsg := &lnwire.Error{ ChanID: tempChanID, Data: msg, } - fndgLog.Errorf("Failing funding flow: %v", spew.Sdump(errMsg)) + fndgLog.Errorf("Failing funding flow: %v (%v)", fundingErr, + spew.Sdump(errMsg)) if _, err := f.cancelReservationCtx(peer, tempChanID); err != nil { fndgLog.Errorf("unable to cancel reservation: %v", err) @@ -819,8 +838,7 @@ func (f *fundingManager) handleFundingOpen(fmsg *fundingOpenMsg) { if len(f.activeReservations[peerIDKey]) >= cfg.MaxPendingChannels { f.failFundingFlow( fmsg.peerAddress.IdentityKey, fmsg.msg.PendingChannelID, - lnwire.ErrorData{byte(lnwire.ErrMaxPendingChannels)}, - ) + lnwire.ErrMaxPendingChannels) return } @@ -834,8 +852,7 @@ func (f *fundingManager) handleFundingOpen(fmsg *fundingOpenMsg) { } f.failFundingFlow( fmsg.peerAddress.IdentityKey, fmsg.msg.PendingChannelID, - lnwire.ErrorData{byte(lnwire.ErrSynchronizingChain)}, - ) + lnwire.ErrSynchronizingChain) return } @@ -844,8 +861,7 @@ func (f *fundingManager) handleFundingOpen(fmsg *fundingOpenMsg) { if msg.FundingAmount > maxFundingAmount { f.failFundingFlow( fmsg.peerAddress.IdentityKey, fmsg.msg.PendingChannelID, - lnwire.ErrorData{byte(lnwire.ErrChanTooLarge)}, - ) + lnwire.ErrChanTooLarge) return } @@ -871,7 +887,7 @@ func (f *fundingManager) handleFundingOpen(fmsg *fundingOpenMsg) { if err != nil { fndgLog.Errorf("Unable to initialize reservation: %v", err) f.failFundingFlow(fmsg.peerAddress.IdentityKey, - msg.PendingChannelID, []byte(err.Error())) + msg.PendingChannelID, err) return } @@ -890,10 +906,9 @@ func (f *fundingManager) handleFundingOpen(fmsg *fundingOpenMsg) { msg.MaxValueInFlight, msg.HtlcMinimum, msg.ChannelReserve, ) if err != nil { - f.failFundingFlow( - fmsg.peerAddress.IdentityKey, fmsg.msg.PendingChannelID, - []byte(fmt.Sprintf("Unacceptable channel "+ - "constraints: %v", err)), + fndgLog.Errorf("Unaccaptable channel constraints: %v", err) + f.failFundingFlow(fmsg.peerAddress.IdentityKey, + fmsg.msg.PendingChannelID, err, ) return } @@ -951,9 +966,8 @@ func (f *fundingManager) handleFundingOpen(fmsg *fundingOpenMsg) { err = reservation.ProcessSingleContribution(remoteContribution) if err != nil { fndgLog.Errorf("unable to add contribution reservation: %v", err) - // TODO(roasbeef): verify only sending sane info over f.failFundingFlow(fmsg.peerAddress.IdentityKey, - msg.PendingChannelID, []byte(err.Error())) + msg.PendingChannelID, err) return } @@ -985,7 +999,7 @@ func (f *fundingManager) handleFundingOpen(fmsg *fundingOpenMsg) { if err != nil { fndgLog.Errorf("unable to send funding response to peer: %v", err) f.failFundingFlow(fmsg.peerAddress.IdentityKey, - msg.PendingChannelID, []byte(err.Error())) + msg.PendingChannelID, err) return } } @@ -1028,11 +1042,9 @@ func (f *fundingManager) handleFundingAccept(fmsg *fundingAcceptMsg) { msg.MaxValueInFlight, msg.HtlcMinimum, msg.ChannelReserve, ) if err != nil { - f.failFundingFlow( - fmsg.peerAddress.IdentityKey, fmsg.msg.PendingChannelID, - []byte(fmt.Sprintf("Unacceptable channel "+ - "constraints: %v", err)), - ) + fndgLog.Warnf("Unacceptable channel constraints: %v", err) + f.failFundingFlow(fmsg.peerAddress.IdentityKey, + fmsg.msg.PendingChannelID, err) return } @@ -1070,7 +1082,7 @@ func (f *fundingManager) handleFundingAccept(fmsg *fundingAcceptMsg) { fndgLog.Errorf("Unable to process contribution from %v: %v", fmsg.peerAddress.IdentityKey, err) f.failFundingFlow(fmsg.peerAddress.IdentityKey, - msg.PendingChannelID, []byte(err.Error())) + msg.PendingChannelID, err) resCtx.err <- err return } @@ -1115,7 +1127,7 @@ func (f *fundingManager) handleFundingAccept(fmsg *fundingAcceptMsg) { if err != nil { fndgLog.Errorf("Unable to parse signature: %v", err) f.failFundingFlow(fmsg.peerAddress.IdentityKey, - msg.PendingChannelID, []byte(err.Error())) + msg.PendingChannelID, err) resCtx.err <- err return } @@ -1123,7 +1135,7 @@ func (f *fundingManager) handleFundingAccept(fmsg *fundingAcceptMsg) { if err != nil { fndgLog.Errorf("Unable to send funding complete message: %v", err) f.failFundingFlow(fmsg.peerAddress.IdentityKey, - msg.PendingChannelID, []byte(err.Error())) + msg.PendingChannelID, err) resCtx.err <- err return } @@ -1177,7 +1189,7 @@ func (f *fundingManager) handleFundingCreated(fmsg *fundingCreatedMsg) { // TODO(roasbeef): better error logging: peerID, channelID, etc. fndgLog.Errorf("unable to complete single reservation: %v", err) f.failFundingFlow(fmsg.peerAddress.IdentityKey, - pendingChanID, []byte(err.Error())) + pendingChanID, err) return } @@ -1218,7 +1230,7 @@ func (f *fundingManager) handleFundingCreated(fmsg *fundingCreatedMsg) { if err != nil { fndgLog.Errorf("unable to parse signature: %v", err) f.failFundingFlow(fmsg.peerAddress.IdentityKey, - pendingChanID, []byte(err.Error())) + pendingChanID, err) deleteFromDatabase() return } @@ -1230,7 +1242,7 @@ func (f *fundingManager) handleFundingCreated(fmsg *fundingCreatedMsg) { if err := f.cfg.SendToPeer(peerKey, fundingSigned); err != nil { fndgLog.Errorf("unable to send FundingSigned message: %v", err) f.failFundingFlow(fmsg.peerAddress.IdentityKey, - pendingChanID, []byte(err.Error())) + pendingChanID, err) deleteFromDatabase() return } @@ -1332,11 +1344,12 @@ func (f *fundingManager) handleFundingSigned(fmsg *fundingSignedMsg) { delete(f.signedReservations, fmsg.msg.ChanID) f.resMtx.Unlock() if !ok { - err := fmt.Sprintf("Unable to find signed reservation for "+ + err := fmt.Errorf("Unable to find signed reservation for "+ "chan_id=%x", fmsg.msg.ChanID) - fndgLog.Warnf(err) + fndgLog.Warnf(err.Error()) + // TODO: add ErrChanNotFound? f.failFundingFlow(fmsg.peerAddress.IdentityKey, - pendingChanID, []byte(err)) + pendingChanID, err) return } @@ -1346,8 +1359,9 @@ func (f *fundingManager) handleFundingSigned(fmsg *fundingSignedMsg) { if err != nil { fndgLog.Warnf("Unable to find reservation (peerID:%v, chanID:%x)", peerKey, pendingChanID[:]) + // TODO: add ErrChanNotFound? f.failFundingFlow(fmsg.peerAddress.IdentityKey, - pendingChanID, []byte(err.Error())) + pendingChanID, err) return } @@ -1369,7 +1383,7 @@ func (f *fundingManager) handleFundingSigned(fmsg *fundingSignedMsg) { fndgLog.Errorf("Unable to complete reservation sign complete: %v", err) resCtx.err <- err f.failFundingFlow(fmsg.peerAddress.IdentityKey, - pendingChanID, []byte(err.Error())) + pendingChanID, err) return }