discovery+routing: validate msg flags and max htlc in ChannelUpdates

In this commit, we alter the ValidateChannelUpdateAnn function in
ann_validation to validate a remote ChannelUpdate's message flags
and max HTLC field. If the message flag is set but the max HTLC
field is not set or vice versa, the ChannelUpdate fails validation.

Co-authored-by: Johan T. Halseth <johanth@gmail.com>
This commit is contained in:
Valentine WallaceandJohan T. Halseth authored and Johan T. Halseth committed 2019-01-22 08:42:27 +01:00
1 parent f316cc6c7e
commit 15168c391e
4 files changed
+150 -18

No files matched your search

+31 -3
View File
@@ -5,6 +5,7 @@ import (
"github.com/btcsuite/btcd/btcec"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcutil"
"github.com/davecgh/go-spew/spew"
"github.com/go-errors/errors"
"github.com/lightningnetwork/lnd/lnwire"
@@ -121,11 +122,16 @@ func ValidateNodeAnn(a *lnwire.NodeAnnouncement) error {
}
// ValidateChannelUpdateAnn validates the channel update announcement by
// checking that the included signature covers he announcement and has been
// signed by the node's private key.
func ValidateChannelUpdateAnn(pubKey *btcec.PublicKey,
// checking (1) that the included signature covers the announcement and has been
// signed by the node's private key, and (2) that the announcement's message
// flags and optional fields are sane.
func ValidateChannelUpdateAnn(pubKey *btcec.PublicKey, capacity btcutil.Amount,
a *lnwire.ChannelUpdate) error {
if err := validateOptionalFields(capacity, a); err != nil {
return err
}
data, err := a.DataToSign()
if err != nil {
return errors.Errorf("unable to reconstruct message: %v", err)
@@ -144,3 +150,25 @@ func ValidateChannelUpdateAnn(pubKey *btcec.PublicKey,
return nil
}
// validateOptionalFields validates a channel update's message flags and
// corresponding update fields.
func validateOptionalFields(capacity btcutil.Amount,
msg *lnwire.ChannelUpdate) error {
if msg.MessageFlags&lnwire.ChanUpdateOptionMaxHtlc != 0 {
maxHtlc := msg.HtlcMaximumMsat
if maxHtlc == 0 || maxHtlc < msg.HtlcMinimumMsat {
return errors.Errorf("invalid max htlc for channel "+
"update %v", spew.Sdump(msg))
}
cap := lnwire.NewMSatFromSatoshis(capacity)
if maxHtlc > cap {
return errors.Errorf("max_htlc(%v) for channel "+
"update greater than capacity(%v)", maxHtlc,
cap)
}
}
return nil
}
+8 -2
View File
@@ -2060,12 +2060,18 @@ func (r *ChannelRouter) applyChannelUpdate(msg *lnwire.ChannelUpdate,
return true
}
if err := ValidateChannelUpdateAnn(pubKey, msg); err != nil {
ch, _, _, err := r.GetChannelByID(msg.ShortChannelID)
if err != nil {
log.Errorf("Unable to retrieve channel by id: %v", err)
return false
}
if err := ValidateChannelUpdateAnn(pubKey, ch.Capacity, msg); err != nil {
log.Errorf("Unable to validate channel update: %v", err)
return false
}
err := r.UpdateEdge(&channeldb.ChannelEdgePolicy{
err = r.UpdateEdge(&channeldb.ChannelEdgePolicy{
SigBytes: msg.Signature.ToSignatureBytes(),
ChannelID: msg.ShortChannelID.ToUint64(),
LastUpdate: time.Unix(int64(msg.Timestamp), 0),