routing: validate channel update in failure message

This commit is contained in:
Joost Jager 2018-08-16 21:35:59 +02:00
parent b5fd32ff77
commit a7fec827cc
No known key found for this signature in database
GPG Key ID: AE6B0D042C8E38D9

@ -1801,7 +1801,8 @@ func (r *ChannelRouter) sendPayment(payment *LightningPayment,
// correct block height is. // correct block height is.
case *lnwire.FailExpiryTooSoon: case *lnwire.FailExpiryTooSoon:
update := onionErr.Update update := onionErr.Update
if err := r.applyChannelUpdate(&update); err != nil { err := r.applyChannelUpdate(&update, errSource)
if err != nil {
log.Errorf("unable to apply channel "+ log.Errorf("unable to apply channel "+
"update for onion error: %v", err) "update for onion error: %v", err)
} }
@ -1826,7 +1827,8 @@ func (r *ChannelRouter) sendPayment(payment *LightningPayment,
// and continue with the rest of the routes. // and continue with the rest of the routes.
case *lnwire.FailAmountBelowMinimum: case *lnwire.FailAmountBelowMinimum:
update := onionErr.Update update := onionErr.Update
if err := r.applyChannelUpdate(&update); err != nil { err := r.applyChannelUpdate(&update, errSource)
if err != nil {
log.Errorf("unable to apply channel "+ log.Errorf("unable to apply channel "+
"update for onion error: %v", err) "update for onion error: %v", err)
} }
@ -1838,7 +1840,8 @@ func (r *ChannelRouter) sendPayment(payment *LightningPayment,
// newly updated fees. // newly updated fees.
case *lnwire.FailFeeInsufficient: case *lnwire.FailFeeInsufficient:
update := onionErr.Update update := onionErr.Update
if err := r.applyChannelUpdate(&update); err != nil { err := r.applyChannelUpdate(&update, errSource)
if err != nil {
log.Errorf("unable to apply channel "+ log.Errorf("unable to apply channel "+
"update for onion error: %v", err) "update for onion error: %v", err)
@ -1871,7 +1874,8 @@ func (r *ChannelRouter) sendPayment(payment *LightningPayment,
// finding. // finding.
case *lnwire.FailIncorrectCltvExpiry: case *lnwire.FailIncorrectCltvExpiry:
update := onionErr.Update update := onionErr.Update
if err := r.applyChannelUpdate(&update); err != nil { err := r.applyChannelUpdate(&update, errSource)
if err != nil {
log.Errorf("unable to apply channel "+ log.Errorf("unable to apply channel "+
"update for onion error: %v", err) "update for onion error: %v", err)
} }
@ -1886,7 +1890,8 @@ func (r *ChannelRouter) sendPayment(payment *LightningPayment,
// the update and continue. // the update and continue.
case *lnwire.FailChannelDisabled: case *lnwire.FailChannelDisabled:
update := onionErr.Update update := onionErr.Update
if err := r.applyChannelUpdate(&update); err != nil { err := r.applyChannelUpdate(&update, errSource)
if err != nil {
log.Errorf("unable to apply channel "+ log.Errorf("unable to apply channel "+
"update for onion error: %v", err) "update for onion error: %v", err)
} }
@ -1899,7 +1904,8 @@ func (r *ChannelRouter) sendPayment(payment *LightningPayment,
// now, and continue onwards with our path finding. // now, and continue onwards with our path finding.
case *lnwire.FailTemporaryChannelFailure: case *lnwire.FailTemporaryChannelFailure:
update := onionErr.Update update := onionErr.Update
if err := r.applyChannelUpdate(update); err != nil { err := r.applyChannelUpdate(update, errSource)
if err != nil {
log.Errorf("unable to apply channel "+ log.Errorf("unable to apply channel "+
"update for onion error: %v", err) "update for onion error: %v", err)
} }
@ -2023,15 +2029,20 @@ func pruneEdgeFailure(paySession *paymentSession, route *Route,
paySession.ReportChannelFailure(badChan.ChannelID) paySession.ReportChannelFailure(badChan.ChannelID)
} }
// applyChannelUpdate applies a channel update directly to the database, // applyChannelUpdate validates a channel update and if valid, applies it to the
// skipping preliminary validation. // database.
func (r *ChannelRouter) applyChannelUpdate(msg *lnwire.ChannelUpdate) error { func (r *ChannelRouter) applyChannelUpdate(msg *lnwire.ChannelUpdate,
pubKey *btcec.PublicKey) error {
// If we get passed a nil channel update (as it's optional with some // If we get passed a nil channel update (as it's optional with some
// onion errors), then we'll exit early with a nil error. // onion errors), then we'll exit early with a nil error.
if msg == nil { if msg == nil {
return nil return nil
} }
if err := ValidateChannelUpdateAnn(pubKey, msg); err != nil {
return err
}
err := r.UpdateEdge(&channeldb.ChannelEdgePolicy{ err := r.UpdateEdge(&channeldb.ChannelEdgePolicy{
SigBytes: msg.Signature.ToSignatureBytes(), SigBytes: msg.Signature.ToSignatureBytes(),
ChannelID: msg.ShortChannelID.ToUint64(), ChannelID: msg.ShortChannelID.ToUint64(),