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:
1 parent
f316cc6c7e
commit
15168c391e
4 files changed
+150
-18
No files matched your search
@@ -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
@@ -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),
|
||||
|
||||
Reference in new issue
Block a user