funding: only send know errors across wire

This commit changes the failFundingFlow to accept an error, which will
only be sent to the remote the peer if it is among the
ReservationErrors or ErrorCode. This is done to ensure we don't send
errors that contain information we don't want to leak.
This commit is contained in:
Johan T. Halseth 2018-02-27 18:37:21 +01:00
parent b3441561cf
commit 6942e1479d
No known key found for this signature in database
GPG Key ID: 15BAADA29DA20D26

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